1 00:00:00,000 --> 00:00:06,000 Translated by visionNoob, KNU https://github.com/insurgent92/CS231N_17_KOR_SUB 2 00:00:07,755 --> 00:00:11,682 CS231N 3강입니다. 3 00:00:11,682 --> 00:00:14,594 오늘은 손실함수(Loss functions)와 최적화(Optimization)을 배울겁니다. 4 00:00:14,594 --> 00:00:20,129 진도 나가기에 앞서 공지사항을 전달합니다. 5 00:00:21,094 --> 00:00:24,547 먼저, 첫 번째 과제가 생겼습니다. 6 00:00:24,547 --> 00:00:26,889 웹사이트에서 확인하실 수 있습니다. 7 00:00:26,889 --> 00:00:30,086 과제를 좀 늦게 내드렸기 때문에 8 00:00:30,086 --> 00:00:35,264 4월 20일 목요일 오후 11시 59분으로 기한을 변경합니다. 9 00:00:36,374 --> 00:00:42,702 앞으로 2주정도 라고 보시면 됩니다. 10 00:00:42,702 --> 00:00:49,087 그리고 변경된 기한으로 강의계획서를 업데이트하겠습니다. 11 00:00:49,087 --> 00:00:54,617 과제를 완료하면 zip파일로 Canvas에 업로드해야 하며 12 00:00:54,617 --> 00:00:57,779 가능한 빨리 채점을 하도록 하겠습니다. 13 00:00:58,799 --> 00:01:04,879 다음 사항은 여러분이 공지사항을 확인하려면 항상 Piazza를 체크해야 한다는 것입니다. 14 00:01:04,879 --> 00:01:11,432 이번주에 Piazza에 몇가지 예제 프로젝트를 공고해 놓을 것입니다. 15 00:01:11,432 --> 00:01:17,220 그래서 Stanford 커뮤니티와, 혹은 Stanford와 연계된 분들로부터 프로젝트 아이디와 관련된 예시를 부탁드렸는데, 16 00:01:17,220 --> 00:01:24,583 그리고 그 분들이 이 수업을 듣는 학생들과 함께 프로젝트를 진행하고 싶다는 제안을 해주셨습니다. 17 00:01:24,583 --> 00:01:26,986 그러니 Piazza에 공고를 확인해 보시고 18 00:01:26,986 --> 00:01:34,231 하고싶은 프로젝트가 있으면 자유롭게 프로젝트 멘토와 직접 얘기하면 되겠습니다. 19 00:01:34,231 --> 00:01:37,090 추가적으로 강의 홈피에 근무시간을 게시하였습니다. 20 00:01:37,090 --> 00:01:45,077 구글 캔린더로 게시하였고 학생들이 근무시간에 대해 많이 물어봐서 이번에 게시하였습니다. 21 00:01:45,077 --> 00:01:48,307 마지막 공지는 구글 클라우드 관련된 것입니다. 22 00:01:48,307 --> 00:01:54,331 구글 클라우드에서 우리 강의를 지원하므로 23 00:01:54,331 --> 00:02:00,687 여러분의 과제와 프로젝트를 수행하기 위해 구글 클라우드 크래딧 100$를 지급하였으며 24 00:02:00,687 --> 00:02:05,246 사용하는 방법은 추후 Piazza에 공지하겠습니다. 25 00:02:05,246 --> 00:02:11,977 공지사항에 대한 질문이 없으면 진도를 나가겠습니다. 26 00:02:13,440 --> 00:02:14,273 좋습니다. 27 00:02:15,559 --> 00:02:17,997 저번 2강을 복습해보면 28 00:02:17,997 --> 00:02:20,412 인식에서의 어려운 점을 살펴보았고 29 00:02:20,412 --> 00:02:24,476 데이터 중심의 방식에 초점을 마춰보았습니다. 30 00:02:24,476 --> 00:02:29,160 그리고 이미지 분류에 대해 배웠고 왜 이미지 분류가 어려운지, 그리고 31 00:02:29,160 --> 00:02:35,812 컴퓨터가 보는것과 사람이 보는 것의 차이가 있다는 것도 배웠습니다. 32 00:02:35,812 --> 00:02:42,124 그리고 분류를 어렵게하는 조명의 변화, 변형에 대해 다뤘고 왜 이게 그토록 어려운지에 대해 배웠습니다. 33 00:02:42,124 --> 00:02:47,912 인간의 시각체계는 이 일을 엄청 쉽게 하는데도 말이죠 34 00:02:47,912 --> 00:02:50,421 그리고 KNN 분류기도 배웠습니다. 35 00:02:50,421 --> 00:02:55,309 데이터 중심 접근방법 중에 가장 단순한 방법이었죠. 36 00:02:55,309 --> 00:03:00,824 그리고 CIFAR-10도 배웠습니다. 저기 좌상단에 보이는 이미지들이죠. 37 00:03:00,824 --> 00:03:05,787 CIFAR-10은 비행기, 자동차 등 10개의 카테고리가 있습니다. 38 00:03:05,787 --> 00:03:11,202 그리고 어떻게 KNN을 이용해서 학습 데이터를 가지고 각 카테고리 클래스를 분류하는 39 00:03:11,202 --> 00:03:15,746 결정 경계를 학습시킬 수 있는지도 배웠습니다. 40 00:03:15,746 --> 00:03:25,190 또한 크로스 벨리데이션데 대해서도 배웠고 트레인, 벨리데이션, 테스트셋으로 나눠서 하이퍼파라미터를 찾는 법도 배웠습니다. 41 00:03:25,190 --> 00:03:32,410 그리고 2강 마지막에는 Linear classification에 대해 배웠 습니다. Linear classifier는 뉴럴넷의 기본요소입니다. 42 00:03:32,410 --> 00:03:38,538 Linear classifier는 parametric classifier의 일종입니다. parametric classifier라는 것은 43 00:03:38,538 --> 00:03:45,444 트레이닝 데이터의 정보가 파라미터인 "행렬 W"로 요약된 다는 것을 뜻합니다. 그리고 W가 학습되는 것입니다. 44 00:03:45,444 --> 00:03:48,448 그리고 이 Linear classifier는 상당히 간단합니다. 45 00:03:48,448 --> 00:03:51,810 이미지를 입력받으면 하나의 긴 벡터로 폅니다. 46 00:03:51,810 --> 00:03:54,974 여기 이미지 x가 있고, 47 00:03:54,974 --> 00:04:02,918 이 이미지는 32x32x3 픽셀이고, 이를 긴 열벡터로 펼치게 됩니다. 48 00:04:04,344 --> 00:04:09,722 32x32는 이미지의 높이와 너비이며 3은 이미지의 채널 red, green, blue 입니다. 49 00:04:09,722 --> 00:04:13,561 그리고 파라미터 "행렬 W"가 있는데 50 00:04:13,561 --> 00:04:18,517 이 행렬은 아까 만들었던 이미지 픽셀과 연산하여 51 00:04:18,517 --> 00:04:24,387 CIFAR-10의 각 10개의 클래스에 해당하는 클래스 스코어를 만들어줍니다. 52 00:04:24,387 --> 00:04:29,617 그리고 해석해보면 스코어가 더 큰 값은 53 00:04:29,617 --> 00:04:34,881 가령 고양이 클래스의 스코어가 더 크다는 것은 분류기가 이 이미지가 고양이일것 같다고 생각하는 것입니다. 54 00:04:34,881 --> 00:04:42,443 반대로 개나 자동차 클래스의 스코어가 더 낮다는 것은 이 이미지가 개나 자동차일 확률이 낮다는 것을 의미하는 것입니다. 55 00:04:42,443 --> 00:04:51,625 또한 지난 수업에서 설명이 좀 부족했던 부분이 있었습니다. Linear clssification을 각 클래스 템플릿으로 보는 것인데 56 00:04:51,625 --> 00:05:02,444 좌하단의 다이어그램을 보시면, 행렬 W에는 각 10개의 클래스와 이미지의 모든 픽셀에 대응되는 하나씩의 요소가 있습니다. 57 00:05:02,444 --> 00:05:06,554 그리고 이 것은 "이 픽셀이 클래스를 결정하는데 얼마나 중요한 역할을 하는지"를 의미합니다. 58 00:05:06,554 --> 00:05:12,412 행렬 W의 각 행들이 해당하는 그 클래스의 템플릿이 되는 것입니다. 59 00:05:12,412 --> 00:05:22,551 행렬 W의 각 행은 "이미지의 픽셀 값"과 "해당 클래스" 사이의 가중치가 되기 때문에 60 00:05:22,551 --> 00:05:29,900 그렇기 때문에 우리가 각 행을 풀어서 다시 한 이미지로 재구성하면 각 클래스에 대응하는 학습된 템플릿을 볼 수 있었습니다. 61 00:05:29,900 --> 00:05:35,399 그리고 또한 Linear clssification이 고차원 공간에서의 일종의 "결정 경계"를 학습한다는 측면으로 볼 수 있는데, 62 00:05:35,399 --> 00:05:43,774 그 공간의 차원은 이미지의 픽셀 값에 해당하는 것입니다. 63 00:05:43,774 --> 00:05:47,571 지난 시간에 여기까지 진행했습니다. 64 00:05:47,571 --> 00:05:54,141 지난 시간에는 Linear classifier에 대한 간략한 아이디어만 배우고 끝났습니다. 65 00:05:54,141 --> 00:05:57,554 그때는 실제로 행렬W를 어떻게 만드는지는 다루지 않았습니다. 66 00:05:57,554 --> 00:06:02,628 가장 좋은 행렬W를 구하는데 어떻게 트레이닝 데이터를 활용해야 하는지는 언급하지 않았었습니다. 67 00:06:02,628 --> 00:06:08,292 지난 시간에는 임의의 행렬 W를 사용했었고, 68 00:06:08,292 --> 00:06:12,068 그 행렬 W를 가지고 각 이미지에 해당하는 10개의 클래스 스코어를 계산하였습니다. 69 00:06:12,068 --> 00:06:15,597 이 때의 클래스 스코어는 좋을수도, 나쁠수도 있었습니다. (임의로 정한 것이니까) 70 00:06:15,597 --> 00:06:20,833 여기 간단한 예시가 있는데 세개의 트레이닝 데이터에 대한 71 00:06:20,833 --> 00:06:26,046 임의의 행렬W를 가지고 예측한 10개의 클래스 스코어입니다. 72 00:06:26,046 --> 00:06:29,506 굵게 표시한 각 스코어를 보면 더 좋은것도 있고 나쁜 것도 있다는 것을 볼 수 있습니다. 73 00:06:29,506 --> 00:06:35,924 예컨데 왼쪽의 이미지를 보면 고양이이죠 우리는 인간이니까 아주 쉽게 알 수 있죠. 74 00:06:35,924 --> 00:06:41,068 하지만 고양이에 부여된 확률을 보면, (확률이 아니라 스코어죠) 75 00:06:41,068 --> 00:06:48,082 이 분류기가 cat에는 2.9점을 줬습니다. 76 00:06:48,082 --> 00:06:51,018 반면 frog에는 3.78점을 줬군요 77 00:06:51,018 --> 00:06:57,920 이 분류기는 별로 좋아보이지 않습니다. 우리는 정답 클래스(고양이) 가 가장 높은 점수가 되는 분류기를 원합니다. 78 00:06:57,920 --> 00:07:02,729 반면 다른 예를 살펴봅시다. 자동차를 보면 79 00:07:02,729 --> 00:07:06,819 자동차 이미지에서는 자동차의 스코어가 제일 높습니다. 좋은 거죠 80 00:07:06,819 --> 00:07:14,357 개구리의 예를 보면 스코어가 -4입니다. 오히려 다른 스코어보다도 훨씬 낮습니다. 엄청 안좋은 것입니다. 81 00:07:14,357 --> 00:07:16,531 이렇게 분석하는 방법은 좋지 않습니다. 82 00:07:16,531 --> 00:07:20,654 스코어를 눈으로 훑으면서 어느게 좋고 어느게 나쁜지 살펴보기만 하는것은 좋은 생각이 아닙니다. 83 00:07:20,654 --> 00:07:25,264 이런 알고리즘을 만들고, 어떤 W가 가장 좋은지를 결정하기 위해서는 84 00:07:25,264 --> 00:07:31,032 지금 만든 W가 좋은지 나쁜지를 정량화 할 방법이 필요합니다. 85 00:07:31,032 --> 00:07:41,987 W를 입력으로 받아서 각 스코어를 확인하고 이 W가 지금 얼마나 거지같은지를 정량적으로 말해주는 것이 바로 손실함수입니다. 86 00:07:41,987 --> 00:07:49,782 이번 강의에서는 Image classification에서 쓸만한 몇가지 손실함수를 소개해 드리도록 하겠습니다. 87 00:07:49,782 --> 00:07:52,683 손실함수가 어떤 일을 해야하는지 한번 생각해 보세요. 88 00:07:52,683 --> 00:07:58,498 임의의 값 W가 얼마나 좋은지 나쁜지를 정량화해 줘야 합니다. 89 00:07:58,498 --> 00:08:04,770 우리가 실제로 원하는 것은, 행렬 W가 될 수 있는 모든 경우의 수에 대해서 90 00:08:04,770 --> 00:08:10,688 "가장 덜 구린" W가 무엇인지를 찾고싶은 것입니다. 91 00:08:10,688 --> 00:08:12,860 이 과정이 바로 "최적화 과정" 이며 92 00:08:12,860 --> 00:08:16,276 최적화에 대해서는 좀 있다가 다시 다루겠습니다. 93 00:08:16,276 --> 00:08:21,003 일단 문제를 좀 줄여보겠습니다. 클래스 10개는 다루기가 불편하니깐요 94 00:08:21,003 --> 00:08:28,886 이번 강의에서는 클래스를 3개로 하는 toy 데이터셋을 사용하겠습니다. 95 00:08:28,886 --> 00:08:44,425 이 예제에서 "고양이" 클래스는 잘 분류되지 못했고 "자동차" 는 잘됐고 "개구리"는 최악입니다. 개구리 점수는 다른 것보다 더 낮습니다. 96 00:08:44,425 --> 00:08:48,817 이를 좀 더 공식화해 봅시다. 손실 함수에 대해 생각해보면 97 00:08:48,817 --> 00:08:52,870 트레이닝 데이터 X와 Y가 있고 98 00:08:52,870 --> 00:08:56,196 보통 X는 알고리즘의 입력에 해당하고 99 00:08:56,196 --> 00:09:05,407 Image classification 알고리즘이라면 X는 이미지가 될 것이고 Y는 예측하고자 하는 것이 될 것입니다. 100 00:09:05,407 --> 00:09:08,930 보통은 Y는 레이블이나 타겟이라고 합니다. 101 00:09:08,930 --> 00:09:16,797 Image classification의 경우라면 각 이미지를 CIFAR-10 의 10개의 카테고리 중 하나로 분류하는 것이고, 102 00:09:16,797 --> 00:09:24,414 여기에서 레이블 y는 1에서 10 사이의 정수 값이 됩니다. 프로그래밍 언어에 따라 0에서 9 일수도 있습니다. 103 00:09:24,414 --> 00:09:30,270 어쨌든 이 y라는 정수값은 각 이미지 x의 정답 카테고리를 의미합니다. 104 00:09:30,270 --> 00:09:42,838 앞서 예측 함수를 정의했었죠 입력 이미지 x와 행렬 W를 입력으로 받아서 y를 예측하는 것입니다. 105 00:09:42,838 --> 00:09:46,446 Image classification 문제라면 y는 10개가 되겠습니다. (CIFAR-10의 경우) 106 00:09:46,446 --> 00:09:49,938 그 다음 손실함수 L_i를 정의합니다. 107 00:09:49,938 --> 00:09:56,804 앞서 말씀드린 예측함수 f와 정답 값 Y를 입력으로 받아서는 108 00:09:56,804 --> 00:10:02,510 이 트레이닝 샘플을 얼마나 구리게 예측하는지를 정량화 시켜 줍니다. 109 00:10:02,510 --> 00:10:10,478 그리고 최종 Loss인 "L"은 우리 데이터 셋에서 각 N개의 샘플들의 Loss의 평균이 됩니다. 110 00:10:10,478 --> 00:10:13,432 이 함수는 아주 일반적인 공식입니다. 111 00:10:13,432 --> 00:10:16,421 그리고 Image classification 외에도 다양하게 확장할 수 있습니다. 112 00:10:16,421 --> 00:10:24,426 좀 더 나아가서 다른 딥러닝 알고리즘을 살펴보자면 어떤 알고리즘이던 가장 일반적으로 진행되는 일은, 113 00:10:24,426 --> 00:10:33,535 일단 어떤 X와 Y가 존재하고, 여러분이 만들 파라미터 W에 W가 얼마나 좋은지를 정량화하는 손실 함수를 만드는 것입니다. 114 00:10:33,535 --> 00:10:39,982 결국은 W의 공간을 탐색하면서 의트레이닝 데이터의 Loss를 최소화하는 어떤 W를 찾게 될 것입니다. 115 00:10:41,081 --> 00:10:49,322 구체적으로 한 손실함수의 예를 들어보겠습니다. 이 손실함수는 Image classification에 아주 적합하기도 합니다. 116 00:10:49,322 --> 00:10:52,755 multi-class SVM loss를 대해 알아보겠습니다. 117 00:10:52,755 --> 00:10:59,602 아마 CS229에서 이진 SVM(Support Vector Machine) 본 적이 있을 것입니다. 118 00:11:00,662 --> 00:11:05,263 multi-class SVM은 여러 클래스를 다루기 위한 이진 SVM의 일반화된 형태입니다. 119 00:11:05,263 --> 00:11:11,797 CS229에서 다뤘던 이진 SVM은 두개의 클래스만 다룹니다. 120 00:11:11,797 --> 00:11:15,159 각 데이터는 Positive 또는 Negative로 분류될 뿐입니다. 121 00:11:15,159 --> 00:11:20,762 하지만 여긴 10개의 카테고리가 있기 때문에 여러개의 클래스를 다루려면 이 개념을 좀더 일반화 시켜야 합니다. 122 00:11:20,762 --> 00:11:24,854 그렇기 때문에 multi-class SVM의 손실함수는 조금 재밌게 생겼습니다. 123 00:11:24,854 --> 00:11:29,801 지금부터는 이에 대해 좀 더 자세히 알아보도록 하겠습니다. 124 00:11:29,801 --> 00:11:35,584 각각의 트레이닝 데이터에서 Loss L_i 를 구하는 방법 부터 살펴보겠습니다. 125 00:11:35,584 --> 00:11:43,373 L_i를 구하기 위해 우선 "True인 카테고리" 를 제외한 "나머지 카테고리 Y"의 합을 구합니다. 126 00:11:43,373 --> 00:11:46,204 다시말해 맞지 않는 카테고리를 전부 합치는 것입니다. 127 00:11:46,204 --> 00:11:52,509 그리고 올바른 카테고리의 스코어와 올바르지 않은 카테고리의 스코어를 비교해 봅니다. 128 00:11:52,509 --> 00:11:59,589 만약 올바른 카테고리의 점수가 올바르지 않은 카테고리의 점수보다 더 높으면 129 00:11:59,589 --> 00:12:03,814 그리고 그 격차가 일정 마진(safety margin) 이상이라면, 이 예시에서는 그 마진을 1로 두었죠 130 00:12:03,814 --> 00:12:14,661 이 경우는 True인 스코어가 다른 false 카테고리보다 훨씬 더 크다는 것을 의미합니다. 131 00:12:14,661 --> 00:12:17,663 그렇게 되면 Loss는 0이 됩니다. 132 00:12:17,663 --> 00:12:21,703 이미지 내 정답이 아닌 카테고리의 모든 값들을 합치면 133 00:12:21,703 --> 00:12:27,155 그 값이 바로 한 이미지의 최종 Loss 가 되는 것입니다. 134 00:12:27,155 --> 00:12:31,994 그리고 전체 트레이닝 데이터 셋에서 그 Loss들의 평균을 구합니다. 135 00:12:31,994 --> 00:12:41,263 이걸 수식화 시키면 if-then 으로 표현 할 수 있습니다. (if:)정답 클래스의 스코어의 점수가 제일 높으면 136 00:12:41,263 --> 00:12:49,327 그럼 "then" 은 다음과 같이 나타낼 수 있습니다. then, max(0,s_j - s_yj + 1). 137 00:12:50,496 --> 00:12:54,294 그리고 수식을 보다가 헷갈리 때가 있는데 138 00:12:54,294 --> 00:13:00,920 그러면 직접 손으로 써보면서 이해하면 도움이 됩니다. 139 00:13:00,920 --> 00:13:06,805 그리고 0과 다른 값의 최댓값, Max(0, value) 과 같은 식으로 손실 함수를 만드는데, 140 00:13:06,805 --> 00:13:14,627 이런 류의 손실 함수를 "hinge loss"(경첩)라고 부르기도 합니다. 그래프의 모양때문에 붙혀진 이름입니다. 141 00:13:14,627 --> 00:13:22,275 여기에서 x축은 S_Yi입니다. 실제 정답 클래스의 스코어입니다. 142 00:13:22,275 --> 00:13:25,353 그리고 y축은 Loss입니다. 143 00:13:25,353 --> 00:13:34,174 정답 카테고리의 점수가 올라갈수록 Loss가 선형적으로 줄어드는 것을 알 수 있습니다. 144 00:13:34,174 --> 00:13:40,235 이 로스는 0이 된 이후에도 Safety margin 을 넘어설 때 까지 더 줄어듭니다. 145 00:13:40,235 --> 00:13:44,402 Loss가 0이 됐다는 건 클래스를 잘 분류했다는 뜻입니다. 146 00:13:45,550 --> 00:13:47,836 질문 있나요? 147 00:13:47,836 --> 00:13:52,410 [죄송합니다만, S_Yi가 뭔가요?] 148 00:13:52,410 --> 00:13:55,170 [정답 스코어인가요? ] 149 00:13:55,170 --> 00:13:56,321 네 질문은 150 00:13:56,321 --> 00:14:00,097 S가 어떤 것이고 S_Yi가 어떤 것인지 입니다. 151 00:14:00,097 --> 00:14:07,246 S는 분류기의 출력으로 나온 예측된 스코어 입니다. 152 00:14:07,246 --> 00:14:13,942 가령 1이 고양이고 2가 개면 S_1은 고양이 스코어 S_2는 개 스코어 인 것이죠 153 00:14:13,942 --> 00:14:21,056 Y_i는 이미지의 실제 정답 카테고리 입니다. 정수 값이죠 154 00:14:21,056 --> 00:14:32,683 그러니 S_Y_i는 트레이닝 셋의 i번째 이미지의 정답 클래스의 스코어인 것입니다. 155 00:14:32,683 --> 00:14:33,870 질문 있으십니까? 156 00:14:33,870 --> 00:14:35,921 [질문 중] 157 00:14:35,921 --> 00:14:38,677 질문은, 그럼 정확히 무엇을 계산하는 것인지 입니다. 158 00:14:38,677 --> 00:14:44,590 무엇을 계산하는지는 흥미로운 주제입니다. 앞으로 예제를 살펴보면 답을 찾을 수 있을 것입니다. 159 00:14:44,590 --> 00:14:51,984 이 Loss가 말하고자 하는 것은 정답 스코어가 다른 스코어들보다 높으면 좋다는 것입니다. 160 00:14:51,984 --> 00:14:58,364 정답 스코어는 safty margin(여기에서 1) 을 두고 다른 스코어들 보다 훨씬 더 높아야 합니다. 161 00:14:58,364 --> 00:15:06,534 충분히 높지 않으면 Loss가 높아지게 됩니다. 162 00:15:06,534 --> 00:15:13,223 3개의 트레이닝 데이터셋을 가지고 예를 들어보면 좀 더 감을 익힐 수 있을 것입니다. 163 00:15:13,223 --> 00:15:19,513 여기서는 case space notation을 제거하고 zero one notation을 사용했습니다. 164 00:15:19,513 --> 00:15:26,186 맨 왼쪽의 예시를 보면서 multi-class SVM loss가 계산 되는 과정을 살펴보자면 165 00:15:26,186 --> 00:15:31,913 우선 정답이 아닌 클래스를 순회합니다. 166 00:15:31,913 --> 00:15:39,089 Cat은 정답 클래스이니, Car와 Flog 클래스를 순회합니다. 이제 다시 Car의 경우를 살펴보면 167 00:15:41,088 --> 00:15:48,782 이제 (Car 스코어) 5.1 - (Cat 스코어) 3.2 + 1(magin) 을 구합니다. Cat과 Car를 비교할때 짐작할 수 있는 것은 168 00:15:49,969 --> 00:15:55,134 Car가 Cat보다 더 높으니까 Loss가 발생할 것이라는 것입니다. 169 00:15:55,134 --> 00:15:59,153 이 고양이 이미지의 예시를 보면 170 00:15:59,153 --> 00:16:03,387 2.9의 손실이 발생합니다. Cat-Car 와 Car-Flog를 비교해보면 171 00:16:03,387 --> 00:16:08,480 Car는 3.2, Flog는 -1.7의 에러가 발생합니다. 172 00:16:08,480 --> 00:16:16,409 Cat 스코어는 Frog 스코어보다 훨씬 그므로 Loss는 0이라고 할 수 있습니다. 173 00:16:16,409 --> 00:16:23,094 고양이 이미지의 Multiclass-SVM Loss는 이런 클래스쌍의 Loss의 합이 되며 174 00:16:23,094 --> 00:16:27,112 즉 2.9 + 0 = 2.9 가 되는 것입니다. 175 00:16:27,112 --> 00:16:34,567 여기에서 2.9라는 숫자가 "얼마나 분류기가 이 이미지를 구리게 분류하는지" 에 대한 척도가 되겠습니다. 176 00:16:32,950 --> 00:16:35,367 177 00:16:35,795 --> 00:16:41,574 이런 작업은 여러번 반복합니다. Car 클래스에 다시한번 해보면 178 00:16:41,574 --> 00:16:52,072 Car와 Cat을 비교해 볼 것입니다. Car 스코어가 Cat 스코어보다 높기 때문에 여기에서 Loss는 0이 될 것입니다. 179 00:16:52,072 --> 00:16:57,557 Car 와 Frog도 비교해보면 Car의 스코어가 Frog보다 훨씬 더 크다는 것을 알 수 있습니다. 180 00:16:57,557 --> 00:17:02,993 그러므로 Car 의 경우는 전체 Loss도 0이 되겠습니다. 181 00:17:02,993 --> 00:17:09,051 이미 다들 감을 잡으셨겠지만 개구리, frog의 경우도 한번 봅시다. 182 00:17:09,051 --> 00:17:14,895 Frog와 Cat을 보면 엄청 큰 Loss가 발생함을 알 수 있습니다. Flog스코어가 엄청 낮기 때문이죠. Car와의 경우도 같습니다. 183 00:17:14,895 --> 00:17:19,697 또한 Frog 스코어 자체가 엄청 낮기 때문이죠. 결국 전체 Loss는 12.9가 됩니다. 184 00:17:21,150 --> 00:17:26,578 그리고 전체 트레이닝 셋의 최종 Loss는 각 트레이닝 이미지의 Loss들의 평균이 되겠습니다. 185 00:17:26,578 --> 00:17:29,277 대략 5.3정도 나오는 걸 볼 수 있습니다. 186 00:17:29,277 --> 00:17:34,929 이것이 의미하는 바는, 우리의 분류기가 5.3점 만큼 이 트레이닝 셋을 구리게 분류하고 있다는 "정량적 지표" 가 되는 것입니다. 187 00:17:34,929 --> 00:17:36,732 질문 있으십니까? 188 00:17:36,732 --> 00:17:39,152 [질문 중] 189 00:17:39,152 --> 00:17:41,920 질문은 바로, "1을 더하는 것"은 어떻게 결정하는 것인지 입니다. (safety margin 이 1이었음) 190 00:17:41,920 --> 00:17:43,574 아무 좋은 질문입니다. 191 00:17:43,574 --> 00:17:46,662 이게 아무 숫자나 막 끼워 넣은 것 같아 보이고 192 00:17:46,662 --> 00:17:52,532 이게 또 손실 함수에서 상수 텀으로 자리잡고 있고 그래서 보기에 불쾌할 수도 있는데요 193 00:17:52,532 --> 00:18:00,305 이게 임의로 선택한 숫자같아 보이긴 하지만, 우리는 사실 손실함수의 "스코어가 정확이 몇인지"는 신경쓰지 않습니다. 194 00:18:00,305 --> 00:18:05,389 우리가 궁금한건 여러 스코어 간의 상대적인 차이인 것입니다. 195 00:18:05,389 --> 00:18:08,944 우리가 관심있어 하는건 오로지 정답 스코어가 다른 스코어에 비해 얼마나 더 큰 스코어를 가지고 있는지 입니다. 196 00:18:08,944 --> 00:18:14,742 행렬 W를 전체적으로 스케일링한다고 생각해 보면 결과 스코어도 이에 따라 스케일이 바뀔 것입니다. 197 00:18:14,742 --> 00:18:20,808 이와 관련된 내용이 온라인 코스 노트에 자세히 나와 있습니다. 198 00:18:20,808 --> 00:18:24,362 그걸 보면 1 이라는게 별 상관 없다는 것을 알게 될 것입니다. 199 00:18:24,362 --> 00:18:32,625 1이라는 파라미터는 없어지고, W의 스케일에 의해 상쇄됩니다. 200 00:18:32,625 --> 00:18:35,489 자세한 내용은 온라인 코스노트를 확인해 주시면 되겠습니다. 201 00:18:37,953 --> 00:18:45,374 그 Loss가 실제무 무슨 일을 하는지를 직관적으로 이해하는 것이 중요하므로 다른 질문들로 다시 접근해 보겠습니다. 202 00:18:45,374 --> 00:18:53,349 만약 Car 스코어가 조금 변하면 Loss에는 무슨 일이 일어날까요? 203 00:18:53,349 --> 00:18:54,182 아이디어 있으십니까? 204 00:18:56,479 --> 00:18:59,856 다들 대답하기 무서워 하는것 같네요 205 00:18:59,856 --> 00:19:00,689 정답? 206 00:19:00,689 --> 00:19:04,272 [대답 하는 학생] 207 00:19:06,983 --> 00:19:13,333 대답은 우리가 Car의 스코어를 조금 바꾸더라고 Loss가 바뀌지 않을 것이라고 대답했습니다. 208 00:19:13,333 --> 00:19:21,918 다시 SVM loss를 상기해보면 이 loss는 오직 정답 스코어와 그 외의 스코어와의 차이만 고려했습니다. 따라서 이 경우에는 209 00:19:21,918 --> 00:19:25,506 Car 스코어가 이미 다른 스코어들보다 엄청 높기 때문에 210 00:19:25,506 --> 00:19:35,437 여기 스코어를 조금 바꾼다고 해도, 서로 간의 간격(Margin)은 여전히 유지될 것이고, 결국 Loss는 변하지 않습니다. 계속 0일 것입니다. 211 00:19:36,870 --> 00:19:40,150 다음 질문은 SVM Loss가 가질 수 있는 최댓/최솟값이 어떻게 될까요? 212 00:19:43,265 --> 00:19:44,445 [대답하는 학생] 213 00:19:44,445 --> 00:19:45,764 잘 못들었습니다? 214 00:19:45,764 --> 00:19:52,018 최솟값은 0이 되겠죠. 왜냐하면 모든 클래스에 걸쳐서 215 00:19:52,018 --> 00:19:57,357 정답 클래스의 스코어가 제일 크면 모든 트레이닝 데이터에서 loss가 0이 될테니깐요 216 00:19:57,357 --> 00:20:03,495 그리고 다시 이 손실 함수가 hinge loss 모양이라는 점을 고려해 보면, 217 00:20:03,495 --> 00:20:07,981 만약 정답 클래스 스코어가 엄청 낮은 음수 값을 가지고 있다고 생각해보면, 아마 Loss가 무한대 일 것입니다. 218 00:20:07,981 --> 00:20:11,538 그러니 최솟값은 0이고 최댓값을 무한대 일 것입니다. 219 00:20:11,538 --> 00:20:16,120 또 한가지는, 파라미터를 초기화하고 처음부터 학습시킬때 220 00:20:16,120 --> 00:20:21,242 보통은 행렬W를 임의의 작은 수로 초기화시키는데, 그렇게되면 221 00:20:21,242 --> 00:20:25,535 처음 학습 시에는 결과 스코어가 임의의 일정한 값을 갖게 됩니다. 222 00:20:25,535 --> 00:20:31,449 그렇다면 만약 모든 스코어 S가 거의 "0에 가깝고" 그리고 "값이 서로 거의 비슷하다면" 223 00:20:31,449 --> 00:20:35,740 Multiclass SVM에서 Loss가 어떻게 될 것 같습니까? 224 00:20:35,741 --> 00:20:37,502 - [학생이 답변] 225 00:20:37,502 --> 00:20:43,248 네, 답변은 "클래스의 수 - 1" 이었습니다. 226 00:20:42,448 --> 00:20:53,738 왜냐면 Loss를 계산할때 정답이 아닌 클래스를 순회합니다. 그러면 C - 1 클래스를 순회하겠죠. 비교하는 두 스코어가 거의 비슷하니 227 00:20:53,738 --> 00:20:57,536 Margin때문에 우리는 1 스코어를 얻게 될 것입니다. 그리고 전에 Loss는 C - 1을 얻게 되는 것이죠 228 00:20:57,536 --> 00:21:01,964 이는 실제로 유용합니다. 특히 "디버깅 전략"으로 말이죠 229 00:21:01,964 --> 00:21:04,734 여러분들이 이런 전략을 가지고 트레이닝을 시작한다면 230 00:21:04,734 --> 00:21:08,082 여러분들은 Loss가 어떻게 될지를 짐작할 수 있게 됩니다. 231 00:21:08,082 --> 00:21:14,999 다시말해 트레이닝을 처음 시작할때 Loss가 C-1이 아니라면 232 00:21:14,999 --> 00:21:16,353 아마 버그가 있는 것이고 고쳐야 할 것입니다. 233 00:21:16,353 --> 00:21:20,905 실제로 아무 유용합니다. 234 00:21:21,886 --> 00:21:31,487 또 다른 질문입니다. SVM Loss는 정답인 클래스는 빼고 다 더했습니다. 그렇다면 정답인 놈도 같이 더하면 어떻게될까요? 235 00:21:31,487 --> 00:21:34,323 만약 다 더하면? 236 00:21:34,323 --> 00:21:36,034 - [학생이 대답] 237 00:21:36,034 --> 00:21:39,326 답은 Loss에 1이 더 증가한다는 것입니다. 238 00:21:39,326 --> 00:21:45,052 일제로 우리가 정답 클래스만 빼고 계산하는 이유는, 일반적으로 Loss가 0이 되야지만 239 00:21:45,052 --> 00:21:52,755 우리가 "아무것도 잃는 것이 없다"고 쉽게 해석할 수 있으며. 240 00:21:52,755 --> 00:21:56,484 Loss에 모든 클래스를 다 더한다고 해서 다른 분류기가 학습되는 것은 아닙니다. 241 00:21:56,484 --> 00:22:02,729 하지만 관례상 정답 클래스는 빼고 계산을 하며, 그렇게 되면 최소 Loss는 0이 됩니다. 242 00:22:04,931 --> 00:22:08,008 또다른 질문입니다. Loss에서 전체 합을 쓰는게 아니라 평균을 쓰면 어떻게 될까요? 243 00:22:09,943 --> 00:22:11,233 - [학생] 244 00:22:11,233 --> 00:22:13,076 네 답은 영향을 미치지 않는다는 것입니다. 245 00:22:13,076 --> 00:22:15,788 클래스의 수는 어짜피 정해져 있으니 246 00:22:15,788 --> 00:22:20,500 평균을 취한다는건 그저 손실 함수를 리스케일 할 뿐입니다. 247 00:22:20,500 --> 00:22:23,991 그러니 상관이 없을 것입니다. 단지 스케일만 변할 뿐입니다. 248 00:22:23,991 --> 00:22:29,664 왜냐하면 우리는 스코어 값이 몇인지는 신경쓰지 않기 때문입니다. 249 00:22:30,541 --> 00:22:37,934 자 이제 또 다른 질문입니다. 만약 우리가 손실함수를 아래와 같이 제곱 항으로 바꾸면 어떻게 될까요? 250 00:22:37,934 --> 00:22:42,968 그럼 결과가 달라질까요 같이질까요? 251 00:22:42,968 --> 00:22:44,178 - [학생] 252 00:22:44,178 --> 00:22:45,213 결과는 달라질 것입니다. 253 00:22:45,213 --> 00:22:50,903 좋은것 과 나쁜것 사이의 트레이드 오프를 비 선형적인 방식으로 바꿔주는 것인데요 254 00:22:50,903 --> 00:22:54,264 그렇게 되면 손실함수의 계산 자체가 바뀌게 됩니다. 255 00:22:54,264 --> 00:22:59,915 실제로도 squared hinge loss를 종종 사용합니다. 256 00:22:59,915 --> 00:23:05,066 이는 여러분들이 손실함수를 설계할때 쓸 수 있는 한가지 방법이 될 수 있습니다. 257 00:23:05,066 --> 00:23:07,831 질문 있나요? 258 00:23:07,831 --> 00:23:11,596 - [학생] 259 00:23:11,596 --> 00:23:16,760 질문은, 왜 굳이 제곱 항을 고려해야 하냐는 것입니다. 260 00:23:16,760 --> 00:23:22,281 손실 함수의 요지는 "얼마나 구린지"를 정량화 하는 것입니다. 261 00:23:22,281 --> 00:23:25,143 그리고 분류자가 다양한 종류의 실수를 저지르고 있다면, 262 00:23:25,143 --> 00:23:30,141 어떻게 해야 이 분류기가 만드는 다양한 Loss들 마다 상대적으로 패널티를 부여할 수 있을까요? 263 00:23:30,141 --> 00:23:37,834 만약 Loss에 제곱을 한다면 이제 "엄청 엄청 안좋은 것들" 은 정말로 "곱절로 안좋은 것" 이 됩니다. 264 00:23:37,834 --> 00:23:39,192 그러니 정말로 나빠지게 되는겁니다. 265 00:23:39,192 --> 00:23:43,623 마치 우리가 심하게 잘못 분류되는 것들을 정말 원하지 않는 것이 됩니다. 266 00:23:43,623 --> 00:23:47,321 반면에 hinge loss를 사용하게 되면 267 00:23:47,321 --> 00:23:52,553 실제로 "조금 잘못된 것" 과 "많이 잘못된 것" 을 크게 신경쓰지 않게 되는 것입니다. 268 00:23:52,553 --> 00:23:57,051 만약 "많이 잘못된 것" 이 있다면 우리는 Loss를 증가시키고 학습을 통해 Loss를 줄일 것인데 269 00:23:57,051 --> 00:24:04,375 그 줄어드는 Loss의 량이 "조금 잘못된 것"이던 "많이 잘못된 것" 이던 큰 차이가 없을 것입니다. 270 00:24:04,375 --> 00:24:06,268 제가 좀 개략적으로 말씀드리긴 했지만 271 00:24:06,268 --> 00:24:13,597 둘 중 어떤 loss를 선택하느냐는 우리가 에러에 대해 얼마나 신경쓰고 있고, 그것을 어떻게 정량화 할 것인지에 달려있습니다. 272 00:24:13,597 --> 00:24:17,938 그리고 이 문제는 실제 여러분들이 손실함수를 만들때 고려해야만 하는 것입니다. 273 00:24:17,938 --> 00:24:22,770 왜냐하면 손실 함수라는 것이 여러분이 여러분들의 알고리즘에게 "어떤 에러를 내가 신경쓰고 있는지" 274 00:24:22,770 --> 00:24:26,267 그리고 "어떤 에러가 트레이드오프 되는 것인지" 를 알려주는 것입니다. 275 00:24:26,267 --> 00:24:30,407 그러니 실제로는 여러분들의 문제에 따라서 손실함수를 잘 설계하는 것은 엄청 중요하다고 할 수 있습니다. 276 00:24:32,315 --> 00:24:40,962 여기 Numpy 코드가 있습니다. 아마 여러분들도 첫 과제에서 이처럼 구현해야 할 것입니다. 277 00:24:40,962 --> 00:24:48,768 여기서 말씀드리고 싶었던건 Numpy를 사용하면 코드 몇줄이면 이 손실 함수를 코딩할 수 있다는 것입니다. 278 00:24:48,768 --> 00:24:50,926 여기 재미있는 기법을 하나 볼 수 있습니다. 279 00:24:50,926 --> 00:24:57,856 max로 나온 결과에서 정답 클래스만 0으로 만들어 주는 것이죠 (margin[y] = 0) 280 00:24:57,856 --> 00:25:06,069 이것은 굳이 전체를 순회할 필요가 없게 해주는 일종의 vectorized 기법입니다. 281 00:25:06,069 --> 00:25:09,854 전체 합을 구할때 제외하고 싶은 부분만 0으로 만들어줍니다. 282 00:25:09,854 --> 00:25:13,315 아마 과제를 할 때 아주 유용할 것입니다. 283 00:25:13,315 --> 00:25:17,106 자 이제 손실 함수에 대한 또 다른 질문이 있습니다. 284 00:25:17,106 --> 00:25:24,139 운이 좋게도 W가 0인 정답을 찾았다고 해 봅시다. 잃은 것이 전혀 없는 것이고, 여러분이 이긴 것입니다! 285 00:25:24,139 --> 00:25:32,390 그렇다면 여기서 질문입니다. 이렇게 Loss가 0이 되게 하는 W가 유일하게 하나만 존재하는 것일까요? 286 00:25:33,251 --> 00:25:34,271 - [학생] 287 00:25:34,271 --> 00:25:37,444 맞습니다. 다른 W도 존재합니다. 288 00:25:37,444 --> 00:25:43,976 특히나 좀 전에도 언급했듯이 W의 스케일은 변합니다. 289 00:25:43,976 --> 00:25:52,978 그렇다면 W에 두배를 한다고 해도 변하지 않을 것입니다. (double double U 니까 quad U인가요?, 모르겠네요) 290 00:25:52,978 --> 00:25:54,110 [웃음] 291 00:25:54,110 --> 00:25:56,601 어쨋든 그 W도 역시 Loss가 0 이겠죠 292 00:25:56,601 --> 00:25:58,568 그래서 이것의 구체적인 예로서, 293 00:25:58,568 --> 00:26:00,066 좋아하는 예제로 돌아갈 수 있습니다. 294 00:26:00,066 --> 00:26:01,184 어쩌면 숫자를 통해 일할 수도 있습니다. 295 00:26:01,184 --> 00:26:02,351 나중에 조금, 296 00:26:02,351 --> 00:26:10,583 만약 여러분에게 W와 2W가 있다면, 정답 스코어 와 정답이 아닌 스코어의 차이의 마진(margins)또한 두배가 될 것입니다. 297 00:26:10,583 --> 00:26:14,521 그러니 모든 마진(margins)이 이미 1보다 더 크다면, 우리가 두배를 한다고 해도 298 00:26:14,521 --> 00:26:18,857 여전히 1보다 클 것이고 Loss가 0 일 것입니다. 299 00:26:20,180 --> 00:26:24,572 여기서 아주 흥미로운 점이 있습니다. 300 00:26:24,572 --> 00:26:29,045 손실 함수 라는 것이. 분류기에게 우리는 어떤 W를 찾고 있고 어떤 W에 신경쓰고 있는지를 말해주는 것이라면 301 00:26:29,045 --> 00:26:31,795 이것은 조금 이상합니다. "불일치" 하는 점이 있습니다. 302 00:26:31,795 --> 00:26:39,112 다양한 W중 Loss가 0인 것을 선택하는 것은 모순입니다. 303 00:26:40,099 --> 00:26:45,303 왜냐하면 여기에서는 오직 데이터의 loss에 대해서만 신경쓰고 있고 304 00:26:45,303 --> 00:26:52,239 그리고 분류기에게 트레이닝 데이터에 꼭 맞는 W를 찾으라고 말하는 것 과 같습니다. 305 00:26:52,239 --> 00:26:56,465 하지만 실제로 우리는 트레이닝 데이터에 얼마나 꼭 맞는지는 전혀 신경쓰지는 않습니다. 306 00:26:56,465 --> 00:27:01,553 기계학습의 핵심은, 트레이닝 데이터를 이용해서 어떤 분류기를 찾는 것인데 307 00:27:01,553 --> 00:27:04,222 그 분류기는 테스트 데이터에 적용할 것이기 때문입니다. 308 00:27:04,222 --> 00:27:06,858 그러니 우리는 트레이닝 데이터의 성능에는 관심이 있는 것이 아니라 309 00:27:06,858 --> 00:27:10,928 우리는 테스트 데이터에서의 성능에 관심이 있는 것입니다. 310 00:27:10,928 --> 00:27:16,176 그러니 분류기에게 트레이닝 데이터의 Loss에만 신경쓰라고 한다면 311 00:27:16,176 --> 00:27:20,307 아마 좋지 않은 상황이 벌어질 것입니다. 312 00:27:20,307 --> 00:27:24,079 아마 분류기가 이해할 수 없는 행동을 할 수도 있습니다. 313 00:27:24,079 --> 00:27:27,786 좀 더 구체적인 예를 들어 보겠습니다. 314 00:27:27,786 --> 00:27:32,918 하지만 지금의 예는, 지금까지 배웠던 선현 분류기에 대한 것은 아니고 기계학습에서 다루는 좀 더 일반적인 개념이라 보시면 됩니다. 315 00:27:32,918 --> 00:27:35,815 여기 파란 점의 데이터 셋이 있습니다. 316 00:27:35,815 --> 00:27:39,827 이제 우리가 할 일은 어떤 곡선을 가지고 저 파란색 점들에 피팅시키는 것입니다. 317 00:27:39,827 --> 00:27:44,532 우리가 분류기에게 유일하게 말할 수 있는 것은, 그저 트레이닝 데이터에 핏 하게 하라고 말하는 것입니다. 318 00:27:44,532 --> 00:27:49,647 그러면 분류기는 모든 트레이닝 데이터를 완벽하게 분류해 내기 위해서 구불구불한 곡선을 만들 것입니다. 319 00:27:49,647 --> 00:27:53,519 하지만 이러면 안좋습니다. 왜냐하면 이 상황에서는 "성능" 에 대해서 전혀 고려하지 않았기 때문입니다. 320 00:27:53,519 --> 00:27:56,329 우린 항상 테스트 데이터의 성능을 고려해야 합니다. 321 00:27:56,329 --> 00:28:00,710 만약 새로운 데이터가 들어오게 되면 322 00:28:00,710 --> 00:28:03,872 앞서 만든 구불구불한 곡선은 완전히 틀리게 됩니다. 323 00:28:03,872 --> 00:28:09,334 사실 우리가 의도했던건 초록색 선인 것입니다. 324 00:28:09,334 --> 00:28:15,171 완벽하게 트레이닝 데이터에 핏한 복잡하고 구불 구불한 곡선을 원한 것이 아닌 것입니다. 325 00:28:15,171 --> 00:28:19,232 이는 기계학습에서 가장 중요한 문제 입니다. 326 00:28:19,232 --> 00:28:22,816 그리고 보통 이를 해결하는 방법을 통틀어 Regularization이라 합니다. 327 00:28:22,816 --> 00:28:26,443 손실 함수에 항을 하나 추가합니다. 328 00:28:26,443 --> 00:28:30,255 "Data Loss Term"에서는 분류기가 트레이닝 데이터에 핏하게 하고 329 00:28:30,255 --> 00:28:36,057 또한, 보통 손실 함수에 "Regularization term"을 추가하는데 330 00:28:36,057 --> 00:28:40,691 이는 모델이 좀 더 단순한 W를 선택하도록 도와줍니다. 331 00:28:40,691 --> 00:28:45,992 "단순하다" 라는 개념은 우리가 해결해야 할 문제나 모델에 따라 조금씩 달라집니다. 332 00:28:47,925 --> 00:28:52,868 과학 계에서 널리 쓰이는 "오컴의 면도날" 이라는 말이 있습니다. 333 00:28:52,868 --> 00:28:59,158 만약 여러분들에게 다양한 가설들을 가지고 있고, 그 가설들 모두가 어떤 현상에 대해 설명 가능하다면 334 00:28:59,158 --> 00:29:01,039 그럼 여러분은 일반적으로 "더 단순한 것" 을 선호해야 한다는 것입니다. 335 00:29:01,039 --> 00:29:06,801 왜냐하면 좀 "더 일반적인(더 단순한)" 것이 미래1에 일어날 현상을 잘 설명할 가능성이 더 높기 때문입니다. 336 00:29:06,801 --> 00:29:12,538 그리고 기계학습에서는 이런 류의 직관을 써먹기 위해서 "Regularization penalty"라는 것을 만들어 냈습니다. 337 00:29:12,538 --> 00:29:15,121 Regularization은 보통 R로 표기합니다. 338 00:29:16,312 --> 00:29:20,409 그렇게 되면, 일반적인 손실 함수의 형태는 두가지 항을 가지게 됩니다. 339 00:29:20,409 --> 00:29:22,417 Data loss와 Regularization loss입니다. 340 00:29:22,417 --> 00:29:27,200 그리고 하이퍼파라미터인 람다(lambda)도 생겼습니다. 두 항 간의 트레이드오프입니다. 341 00:29:27,200 --> 00:29:31,054 지난 강의에서 하이퍼파라미터와 크로스벨리데이션을 배웠습니다. 342 00:29:31,054 --> 00:29:39,363 여기 Regularization의 하이퍼파라미터 람다는 실제로 여러분들이 모델을 훈련시킬 때 고려해야 할 중요한 요소 중 하나입니다. 343 00:29:40,229 --> 00:29:41,062 질문 있나요? 344 00:29:42,097 --> 00:29:48,846 - [학생 질문] 345 00:29:50,685 --> 00:29:51,941 질문은 바로 346 00:29:51,941 --> 00:29:58,072 Wx + lambda R 이란 것이 도대체 뭐길래 구불구불한 곡선을 직선으로 바꿔 준다는 것입니까? 라는 것입니다. 347 00:29:59,912 --> 00:30:03,550 사실 그 부분을 깊에 다루려면 너무 오래걸려서 여기에서는 언급하려 하지 않았습니다. 348 00:30:03,550 --> 00:30:09,830 하지만 짐작해 볼 수 있습니다. 여러분들에게 회귀문제가 있습니다. 일종의 다항식 기저 함수로 나타낼 수 있겠죠 349 00:30:09,830 --> 00:30:15,775 일반적으로 모델은 고차 다항식을 이용해서 문제를 풀려 할 것입니다. 350 00:30:15,775 --> 00:30:25,569 여기에 어떤 regression term을 추가하면 모델이 데이터를 핏 할 떄 저차 다항식을 더 선호하도록 하게 하는 것입니다. 351 00:30:25,569 --> 00:30:29,021 그러니 여러분은 Regularization의 두 가지 역할에 대해 생각해 볼 수 있습니다. 352 00:30:29,021 --> 00:30:32,897 하나는 여러분의 모델이 더 복잡해 지지 못하도록 하는 것이고 353 00:30:32,897 --> 00:30:40,846 또는 모델에 soft penalty를 추가하는 것으로 보는 것입니다. 모델은 여전히 더 복잡한 모델이 될 가능성이 있는 것입니다. 354 00:30:40,846 --> 00:30:43,112 이 다항식의 예라면, 더 복잡한 차수에도 접근할 수 있는 것이지요 355 00:30:43,112 --> 00:30:51,316 하지만 이 soft한 제약을 하나 추가하면, "만약 너가 복잡한 모델을 계속 쓰고싶으면, 이 penalty를 감수해야 할 거야!" 라는 것과 같습니다. 356 00:30:51,316 --> 00:30:55,282 이것으로 인해 완전한 선형 분류문제가 되진 않겠지만 357 00:30:55,282 --> 00:31:01,691 많은 사람들이 "Regularization"에 대해 이런 식으로 떠올립니다. 358 00:31:02,731 --> 00:31:06,917 실제로 Regularization에는 여러 종류가 있습니다. 359 00:31:06,917 --> 00:31:11,022 가장 보편적인 것은 L2 Regularization입니다. Weight decay라고도 하죠. 360 00:31:11,022 --> 00:31:13,905 이 외에도 다양한 것이 많습니다. 361 00:31:13,905 --> 00:31:19,470 L2 Regularization은 가중치 행렬W에 대한 Euclidean Norm입니다. 362 00:31:19,470 --> 00:31:21,892 간혹 squared norm이라고도 하죠 363 00:31:21,892 --> 00:31:26,738 또는 1/2 * squared norm 을 사용하기도 합니다. 미분이 더 깔끔해집니다. 364 00:31:26,738 --> 00:31:32,650 하지만 L2 Regularization의 주요 아이디어는 가중치 행렬 W의 euclidean norm에 패널티를 주는 것입니다. 365 00:31:32,650 --> 00:31:38,957 그리고 L1 regularization도 보게 될 것인데, 이는 L1 norm으로 W에 패널티를 부과하는 것입니다. 366 00:31:38,957 --> 00:31:46,401 L1 Regularization을 하면 행렬 W가 희소행렬이 되도록 합니다. 367 00:31:46,401 --> 00:31:52,744 그리고 Elastic net regularization도 있습니다. L1과 L2를 짬뽕해놓은 것이죠 368 00:31:52,744 --> 00:32:00,004 간혹 Max norm regularization도 보게 될 것입니다. L1, L2 대신에 max norm을 쓰는 것이죠 369 00:32:01,119 --> 00:32:07,374 하지만 이런 regularization은 딥러닝에서만 쓰는 것이 아니라 많은 기계학습 분야를 통틀어서 자주 사용하는 것입니다. 370 00:32:07,374 --> 00:32:10,997 심지어는 더 광범위하게 최적화 할 수도 있습니다. 371 00:32:10,997 --> 00:32:17,138 Regularization 기법 중 특히나 딥러닝에 관련된 기법들을 앞으로 배우게 될 것입니다. 372 00:32:17,138 --> 00:32:25,157 예를 들어, 앞으로 배울 Dropout이나 Batch Normalization , Stochastic depth와 같은 최근 아주 쩌는 것들이죠 373 00:32:25,157 --> 00:32:37,061 Regularization은 모델이 트레이닝 데이터셋에 완벽히 핏 하지 못하도록 모델의 복잡도에 패널티를 부여하는 방법입니다. 374 00:32:37,061 --> 00:32:38,306 질문 있나요? 375 00:32:38,306 --> 00:32:41,889 [말하는 학생] 376 00:32:44,858 --> 00:32:50,186 질문은, "L2 Regularization이 모델이 복잡한지 아닌지를 어떻게 알(측정) 수 있냐" 는 것입니다. 377 00:32:50,186 --> 00:32:54,202 고맙게도 다음에 할 내용이 바로 그것입니다. 378 00:32:55,437 --> 00:33:00,058 여기 한 예시가 있습니다. 트레이닝 데이터 x가 있고 서로 다른 두개의 W가 있습니다. 379 00:33:00,058 --> 00:33:07,157 x는 4줄짜리 벡터이고, 여기에 두개의 서로 다른 W에 대해 생각해 볼 수 있겠습니다. x = [1 1 1 1] 380 00:33:07,157 --> 00:33:10,367 하W중 하나는 처음에만 1이 있고 나머지 세 원소는 0입니다. w1 = [1 0 0 0] 381 00:33:10,367 --> 00:33:14,191 다른 하나는 원소가 모두 0.25입니다. w2 = [0.25 0.25 0.25 0.25] 382 00:33:14,191 --> 00:33:19,702 이걸 가지고 Linear classification을 할때 우리는 x와 w의 내적을 구합니다.(dot product) 383 00:33:19,702 --> 00:33:24,747 Linear classification의 관점에서 w1와 w2는 같습니다. 384 00:33:24,747 --> 00:33:28,302 왜냐하면 x와의 내적이 서로 같기 때문이죠. 385 00:33:28,302 --> 00:33:34,383 여기서 문제는, w1, w2중 L2 regression이 더 선호하는것은 어떤 것일까요? 386 00:33:36,052 --> 00:33:41,030 L2 regression은 w2를 더 선호할 것입니다. 왜냐면 L2 regression에서는 w2가 더 norm이 작기 때문이죠 387 00:33:41,030 --> 00:33:49,440 그러니 L2 Regression은 분류기의 복잡도를 상대적으로 w1와 w2중 어떤 것이 더 coarse한지를 측정합니다. (값이 매끄러워야함) 388 00:33:49,440 --> 00:34:01,920 Linear classification에서 W가 의미하는 것은, "얼마나 x가 Output Class와 닮았는지" 입니다. 389 00:34:01,920 --> 00:34:09,080 그러니 L2 Regularization이 말하고자 하는것은 x의 모든 요소가 영향을 줬으면 하는 것입니다. 390 00:34:09,080 --> 00:34:14,585 그러니 변동이 심한 어떤 입력 x가 있고 그 x의 특정 요소에만 의존하기 보다 391 00:34:14,585 --> 00:34:22,059 모든 x의 요소가 골고루 영향을 미치길 원한다면, L2 Regularization을 통해 더 강인해 질 수 있을 것입니다. 392 00:34:22,060 --> 00:34:26,839 반면 L1 Regularization의 경우에는 정 반대입니다. 393 00:34:26,839 --> 00:34:32,946 L1 Regularization을 쓰게 되면 W2보다는 W1을 더 선호하게 됩니다. 394 00:34:32,946 --> 00:34:35,595 L1 Regularization은 "복잡도"를 다르게 정의합니다. 395 00:34:35,595 --> 00:34:46,080 L1 Regularization은 가중치 W에 0의 갯수에 따라 모델의 복잡도를 다룹니다. 396 00:34:46,080 --> 00:34:51,917 그러니 "복잡도" 을 어떻게 정의하느냐, 그리고 L2 Regularization은 "복잡도"을 어떻게 측정하느냐는 397 00:34:51,917 --> 00:34:54,196 우리가 어떤 문제를 가지고 있으냐에 따라 다릅니다. 398 00:34:54,196 --> 00:34:58,921 그러니 여러분이 어떤 문제가 있고, 어떤 모델이 있고 데이터가 있을때 399 00:34:58,921 --> 00:35:02,837 여러분은 이 문제에서 "복잡하다"는 것을 어떻게 정의할 지를 반드시 고민해야 할 것입니다. 400 00:35:03,921 --> 00:35:04,788 질문 있나요? 401 00:35:04,788 --> 00:35:09,129 - [학생] 402 00:35:09,129 --> 00:35:10,385 네 맞습니다. 403 00:35:10,385 --> 00:35:13,830 w1과 w2의 경우에는 L1의 값이 같습니다. 404 00:35:15,193 --> 00:35:21,546 하지만 여러분은 L1 Regularization이 선호하는 w1를 손쉽게 만들어 볼 수 있습니다. 405 00:35:21,546 --> 00:35:26,908 L1에 대한 일반적인 직관은 "일반적으로 L1은 sparse한 solutions을 선호한다"는 것입니다. 406 00:35:26,908 --> 00:35:35,016 그리고 이것은 W의 요소 중 대부분이 0이 되게 할 것입니다. 407 00:35:35,016 --> 00:35:40,191 그렇게 때문에 L1이 "복잡하다"고 느끼고 측정하는 것은 0이 아닌 요소들의 갯수가 될 수 있습니다. 408 00:35:40,191 --> 00:35:45,682 반면 L2의 경우에는 W의 요소가 전체적으로 퍼져있을 때 "덜 복잡하다" 라고 생각하게 됩니다. 409 00:35:45,682 --> 00:35:48,920 그러니 선택은 여러분들의 데이터와 문제에 달려 있습니다. 410 00:35:48,920 --> 00:35:54,584 좀 더 나아가서, 여러분이 Bayesian에 대해 잘 안하면 L2 Regularization을 사용하다는 것을 411 00:35:54,584 --> 00:35:58,897 parameter vector로 Gaussian prior를 쓰는 MAP inference로 볼 수도 있다는 것입니다. 412 00:35:58,897 --> 00:36:05,343 해당 하는 내용이 CS229의 과제에 있었던 것으로 기억하지만 이 강의에서는 더이상 다루지는 않을 것입니다. 413 00:36:05,343 --> 00:36:11,400 지금 우리는 multi-class SVM Loss에 대해 깊게 알아보고 있는 중입니다. 414 00:36:11,400 --> 00:36:12,783 질문 있나요? 415 00:36:12,783 --> 00:36:32,648 [학생 질문] 416 00:36:33,982 --> 00:36:39,798 질문은, Regularization된다고 Hypothesis class가 변하지 않을 것이라는 것입니다. 417 00:36:39,798 --> 00:36:44,036 그리고 Linear classifier 라는 것이 변하지 않을 것이라는 것입니다. 418 00:36:44,036 --> 00:36:50,038 이 Polynomial regression의 예는 확실이 Linear regression은 아닙니다. 419 00:36:50,038 --> 00:36:56,826 입력의 차수가 증가하는 상황에서의 Linear regression으로 볼 수는 있습니다. 420 00:36:56,826 --> 00:37:05,802 이 경우에는 우리가 많은 polynomial coefficients를 사용하고 싶지는 않다는 것을 의미하는 것입니다. 421 00:37:05,802 --> 00:37:07,385 이런 식으로 생각해 보시면 될 것 같습니다. 422 00:37:07,385 --> 00:37:09,290 여러분이 polynomial regression을 한다고 했을때 423 00:37:09,290 --> 00:37:17,963 f(x)=A0 * 1 + A1 * x + A2 * x^2 + A3 * x^3 와 같은 식으로 나타낼 수 있겠죠 424 00:37:17,963 --> 00:37:23,093 이 경우 우리가 가진 parameters는 A집합이 되겠습니다. 425 00:37:24,211 --> 00:37:28,190 A에 penalty를 준다는 것은 polynomial의 차원이 더 적어지도록 하는 것입니다. 426 00:37:28,190 --> 00:37:31,491 Polynomial regression의 경우가 아니라면 실제로 A의 형태로 파라미터가 생기진 않을 것입니다. 427 00:37:31,491 --> 00:37:34,725 여러분이 사용하고 싶은 다른 파마미터를 설정하게 될 것입니다. 428 00:37:34,725 --> 00:37:36,364 그러나 그것은 일반적인 생각입니다, 429 00:37:36,364 --> 00:37:44,285 hypothesis class 중에 더 간단한 것을 선택하기 위해서 우리는 model에 Penalty를 주는 것입니다. 430 00:37:45,229 --> 00:37:50,340 아직 헷갈리면 개인적으로 다시 질문해 주시기 바랍니다. 431 00:37:50,340 --> 00:37:56,349 지금까지 Multi-class SVM Loss에 대해 알아보았습니다. 그리고 부차적으로 또 하나가 있습니다. 432 00:37:56,349 --> 00:38:03,097 지금까지 본 것은 SVM Loss를 Multi class로 확장시킨 아주 일반적인 손실함수일 뿐입니다. 433 00:38:03,097 --> 00:38:06,596 여러 문헌을 찾아보게 되면 몇가지 다른 공식들도 존재합니다. 434 00:38:06,596 --> 00:38:13,813 하지만, 적어도 딥러닝에서는 그런 여러가지 손실함수들이 사실은 거의 비슷하게 동착합니다. 435 00:38:13,813 --> 00:38:19,949 그렇기 때문에, 이 수업에서는 지금까지 배웠던 multi-class SVM loss만 가지고 이야기할 것입니다. 436 00:38:21,061 --> 00:38:25,158 하지만 당연히 여러분이 생각해볼만한 여러 다양한 손실 함수들이 존재합니다. 437 00:38:25,158 --> 00:38:30,603 multi-class SVM loss 외에도 인기있는 것이 하나 있습니다. 438 00:38:31,761 --> 00:38:37,769 딥러닝에서 자주쓰는 Multinomial logistic regression, 즉 softmax입니다. 439 00:38:39,405 --> 00:38:43,222 사실 딥러닝에서는 이걸 더 많이 씁니다. 440 00:38:43,222 --> 00:38:48,127 하지만 몇가지 이유가 있어 두번째로 소개해 드립니다. 441 00:38:48,127 --> 00:38:55,096 multi-class SVM loss에서 우리는 스코어 자체에 대한 해석은 고려하지 않았습니다. 442 00:38:55,096 --> 00:39:02,670 어떤 분류문제가 있고 어떤 모델 F가 각 클래스에 해당하는 10개의 숫자를 출력할때면 443 00:39:02,670 --> 00:39:07,787 mulfi-class SVM의 경우에 우리는 그 스코어 자체는 크게 신경쓰지 않았습니다. 444 00:39:07,787 --> 00:39:13,497 우린 단지 정답 클래스가 정답이 아닌 클래스들 보다 더 높은 스코어를 내기만을 원했죠 445 00:39:13,497 --> 00:39:17,712 그 이상, 스코어 자체가 실제로 의미하는 것에는 관심이 없었습니다. 446 00:39:17,712 --> 00:39:27,668 하지만 Multinomial Logistic regression의 손실함수는 스코어 자체에 추가적인 의미를 부여합니다. 447 00:39:27,668 --> 00:39:33,907 그리고 특히, 저 수식을 이용해서 스코어를 가지고 클래스 별 확률 분포를 계산하게 될 것입니다. 448 00:39:33,907 --> 00:39:37,324 여기에서는 softmax라고 불리는 함수를 쓸 것입니다. 449 00:39:37,324 --> 00:39:43,192 스코어를 전부 이용하는데, 스코어들에 지수를 취해서 양수가 되게 만듭니다. 450 00:39:43,192 --> 00:39:46,540 그리고 그 지수들의 합으로 다시 정규화 시킵니다. 451 00:39:46,540 --> 00:39:53,053 그래서 softmax 함수를 거치게 되면 우리는 결국 확률 분포를 얻을 수 있고 452 00:39:53,053 --> 00:39:55,792 그것은 바로 해당 클래스일 확률이 되는 것입니다. 453 00:39:55,792 --> 00:39:58,193 확률이기 때문에 0에서 1 사이의 값이고 454 00:39:58,193 --> 00:40:02,287 모든 확률들의 합은 1이 됩니다. 455 00:40:03,954 --> 00:40:07,169 이제 한번 해석을 해봅시다. 456 00:40:07,169 --> 00:40:12,020 이게 우리가 스코어를 가지고 계산한 확률 분포가 있습니다. 457 00:40:12,020 --> 00:40:17,138 이제 이 확률값을 실제 값과 비교해 볼 것입니다. 458 00:40:17,138 --> 00:40:26,904 만약 이미지가 고양이라면 실제 고양이 일 확률은 1이 됩니다. 459 00:40:26,904 --> 00:40:29,754 그리고 나머지 클래스의 확률은 0이 됩니다. 460 00:40:29,754 --> 00:40:35,574 내그러니 우리가 지금 하고자 하는 것은 softmax에서 나온 확률이 461 00:40:35,574 --> 00:40:40,671 정답 클래스에 해당하는 클래스의 확률을 1로 나타내게 하는 것입니다. 462 00:40:40,671 --> 00:40:51,102 이런 식은 다양하게 사용될 수 있습니다. 예를 들어 두 분포 간의 KL divergence라던가 463 00:40:51,102 --> 00:40:53,221 아님 이 식은 MLE로 볼 수도 있습니다. 464 00:40:53,221 --> 00:41:00,839 하지만 결국 우리가 원하는 것은 정답 클래스에 해당하는 클래스의 확률이 1에 가깝게 계산되는 것입니다. 465 00:41:00,839 --> 00:41:06,389 그렇게 되면 Loss는 "-log(정답클래스확률)" 이 될 것입니다. 466 00:41:06,389 --> 00:41:09,707 여기에 이것저것 들어가서 헷갈릴 수도 있지만 467 00:41:09,707 --> 00:41:13,524 한번 잘 생각해보면 우린 지금 확률이 1이 되길 원하고 있습니다. 468 00:41:13,524 --> 00:41:17,071 그리고 log는 단조 증가 함수이죠, 이런식으로 증가하죠 469 00:41:17,071 --> 00:41:25,604 그리고 log를 최대화시키는 것이 그냥 확률값을 최대화 시키는 것 보다 쉽습니다. 그러니 우리는 log를 씁니다. 470 00:41:25,604 --> 00:41:32,599 log가 단조증가함수 라고 했었죠 그러니 정답 클래스인, log P 를 최대화 시키는건, lop P가 높았으면 좋겠다는 것인데 471 00:41:32,599 --> 00:41:40,051 그런데 손실 함수는 "얼마나 좋은지" 가 아니라 "얼마나 구린지" 를 측정하는 것이기 때문에 log에 마이너스를 붙힙니다. 472 00:41:40,051 --> 00:41:46,148 이제 SVM의 손실함수는 -log(P(정답클래스)) 로 나타내게 됩니다. 473 00:41:48,909 --> 00:41:51,322 요약을 해보자면 474 00:41:51,322 --> 00:41:57,575 스코어가 있으면, softmax를 거치고, 나온 확률 값이 -log를 추가하면 됩니다. 475 00:42:01,697 --> 00:42:05,043 이제 이게 어떻게 생겼는지 구체적인 예시로 확인해 보겠습니다. 476 00:42:05,043 --> 00:42:14,486 다시 고양이 예제로 돌아가 봅시다. 여기 Linear classifier 의 출력으로 나온 스코어가 있습니다. 477 00:42:14,486 --> 00:42:18,712 이 스코어는 이전에 SVM Loss에서의 예제와 같은 값입니다. 478 00:42:18,712 --> 00:42:25,422 하지만 이제는 스코어 자체를 Loss로 쓰기보다는 이제 스코어를 지수화 시킬 것입니다. 479 00:42:25,422 --> 00:42:26,990 그래서 그들은 모두 긍정적입니다, 480 00:42:26,990 --> 00:42:31,025 그리고 합이 1이 되도록 정규화 시켜 줍니다. 481 00:42:31,025 --> 00:42:35,788 그리고 정답 스코어에만 -log를 씌여줍니다. 482 00:42:36,643 --> 00:42:43,823 이걸 softmax라고 합니다. 또는 다항 로지스틱 회귀라고도 하죠. (multinomial logistic regression) 483 00:42:45,496 --> 00:42:50,750 이전에 여러분이 직관을 얻을 수 있도록 multi-class SVM Loss 몇 가지를 던졌었는데요. 484 00:42:50,750 --> 00:42:57,360 Softmax loss를 이해하는데도 그 질문이 도움이 될 것입니다. 485 00:42:57,360 --> 00:42:58,614 그럼 질문은 486 00:42:58,614 --> 00:43:02,697 softmax loss의 최댓값과 최솟값을 얼마일까요? 487 00:43:04,984 --> 00:43:09,720 여기 log도 있고 합치는 것도 있고 해서 좀 헷갈릴수도 있습니다. 488 00:43:11,298 --> 00:43:15,430 정답은 바로 Loss의 최솟값은 0 이고 최댓값은 무한대입니다. 489 00:43:15,430 --> 00:43:24,467 확률 분포를 한번 생각해 보자면, 우리는 정답 클래스의 확률은 1이 되길 원하고 정답이 아닌 클래스는 0 이 되길 원합니다. 490 00:43:24,467 --> 00:43:31,366 이런 식으로 생각해보면, log안에 있는 어떤 값은 결국 1이 되어야 하는 것입니다. 491 00:43:33,662 --> 00:43:40,917 정답 클래스에 대한 Log 확률이기 때문에 Log(1) = 0 이고, -log(1) 또한 0입니다. 492 00:43:41,893 --> 00:43:46,515 그러므로 고양이를 완벽히 분류했다면 Loss는 0이 될 것입니다. 493 00:43:46,515 --> 00:43:53,582 그렇다면 Loss가 0이 되려면 실제 스코어는 어떤 값이어야 할까요? 494 00:43:55,963 --> 00:44:01,572 아마 정답 스코어는 극단 적으로 높아야 할 것입니다. 거의 무한대에 가깝게 말이죠 495 00:44:01,572 --> 00:44:06,098 여기에서는 지수화를 하고 정규화를 하기 때문에 496 00:44:06,098 --> 00:44:17,509 우리가 확률 1(정답) 과 0(그외) 를 얻으려면, 정답 클래스의 스코어는 +무한대 가 되어야 하고, 나머지는 -무한대 가 되어야 합니다. 497 00:44:17,509 --> 00:44:24,108 컴퓨터는 무한대 계산을 잘 못하기 때문에, Loss가 0인 경우는 절대 없을 것입니다.(유한 정밀도 때문에) 498 00:44:24,108 --> 00:44:29,223 하지만 이론적 해석을 가미하면 0 은 "이론적으로 최소 Loss이다" 라고 보면 됩니다. 499 00:44:29,223 --> 00:44:31,607 최대 손실은 최댓값이 없습니다. 500 00:44:31,607 --> 00:44:39,483 만약 정답 클래스의 확률이 0이고, 거기 -log를 취하면 [-log(0)] 501 00:44:39,483 --> 00:44:46,283 log(0)는 음의 무한대가 되고 따라서 -log(0)는 양의 무한대가 됩니다. 502 00:44:46,283 --> 00:44:47,334 정말 안좋은 경우이겠죠 503 00:44:47,334 --> 00:44:58,563 하지만 이러한 경우 또한 발생하지는 않을 것입니다. 왜냐하면 확률이 0이 되려면 e^syi가 0이 되어야 하는데 504 00:44:58,563 --> 00:45:01,630 그게 가능한 경우는 정답 클래스의 스코어가 음의 무한대일 일 때 뿐이기 떄문입니다. 505 00:45:01,630 --> 00:45:07,117 다시한번 말씀드리자만 "유한 정밀도" 를 가지고는 최댓값(무한대) 최솟값(0)에 도달할 수는 없습니다. 506 00:45:08,863 --> 00:45:14,340 또한 multi-class SVM 손실함수를 이야기할때 디버깅을 할 수 있는 방법에 대해서는 말씀드렸는데요 507 00:45:14,340 --> 00:45:16,401 softmax도 같습니다. 508 00:45:16,401 --> 00:45:21,287 만약 S가 모두 0 근처에 모여있는 작은 수일때 Loss는 어떻게 될까요? 509 00:45:21,287 --> 00:45:22,292 정답? 510 00:45:22,292 --> 00:45:27,045 - [학생] 511 00:45:27,045 --> 00:45:33,352 맞습니다. -log(1/C) 가 되겠죠 512 00:45:33,352 --> 00:45:38,079 log는 분모와 분자를 뒤집을 수 있으니까 -log(1/C)는 log(C)가 됩니다. 513 00:45:38,079 --> 00:45:43,977 softmax를 사용할 때 첫 번째 interation에서 해볼만한 아주 좋은 디버깅 전략입니다. 514 00:45:43,977 --> 00:45:47,894 log(c)가 아니면 뭔가 잘못된 것입니다. 515 00:45:50,051 --> 00:45:54,600 이제 지금까지 배운 두 손실함수를 한번 비교해 보겠습니다. 516 00:45:54,600 --> 00:45:57,532 Linear classification의 설정은 둘다 같은 조건입니다. 517 00:45:57,532 --> 00:46:02,072 행렬 W와 입력을 못하는 것은 둘다 같습니다. 518 00:46:02,072 --> 00:46:09,327 다만 두 손실 함수의 차이점은 바로 "얼마나 구린지" 를 측정하기 위해 스코어를 해석하는 방식이 조금 다르다는 것입니다. 519 00:46:09,327 --> 00:46:17,138 SVM에서는 정답 스코어와, 정답이 아닌 스코어 간의 마진(margins)을 신경썼습니다. 520 00:46:17,138 --> 00:46:26,663 반면 softmax (crossentropy) 는 확률을 구해서 -log(정답클래스) 에 신경을 씁니다. 521 00:46:26,663 --> 00:46:33,216 간혹 이것을.... 아니다 이부분은 건너 뛰겠습니다. 522 00:46:33,216 --> 00:46:34,917 [웃음] 523 00:46:34,917 --> 00:46:40,854 두 손실 함수 간의 차이에 대한 흥미로운 질문이 하나 있습니다. 524 00:46:40,854 --> 00:46:54,042 [어떤 얘기 하다가 다른 예시로 돌림] 여기 있는 예제는 무시하세요 525 00:46:54,042 --> 00:46:59,814 multi-class SVM loss의 예시를 다시 생각해보면 526 00:46:59,814 --> 00:47:06,293 car클래스에서 car의 스코어가 다른 클래스보다 훨씬 높았습니다. 527 00:47:06,293 --> 00:47:11,246 그래서 car스코어를 조금 바꾼다고 해서 SVM Loss가 변하거나 하진 않았죠 528 00:47:11,246 --> 00:47:18,359 왜냐면 SVM loss는 오직 정답과 그 외 클래스의 마진이 얼마나 되는지 에만 관심이 있기 때문입니다. 529 00:47:18,359 --> 00:47:21,726 이런 점에서 softmax loss는 상당히 다릅니다. 530 00:47:21,726 --> 00:47:26,438 softmax는 언제나 확률은 1로 만드려고 노력할 것입니다. 531 00:47:26,438 --> 00:47:34,298 그러니, 정답 스코어가 충분히 높고, 다른 클래스 스코어가 충분히 낮은 상태에서도 532 00:47:34,298 --> 00:47:40,044 softmax는 최대한 정답 클래스에 확률을 몰아 넣으려고 할 것이고 533 00:47:40,044 --> 00:47:46,138 정답 클래스는 무한대로, 그 외의 클래스는 음의 무한대로 보내려 할 것입니다. 534 00:47:46,138 --> 00:47:49,968 그리고 그것은 두 손실 함수 간의 흥미로운 차이점 입니다. 535 00:47:49,968 --> 00:47:57,739 SVM의 경우에는 일정 선(margins)을 넘기만 하면 더이상 성능 개선에 신경쓰지 않습니다. 536 00:47:57,739 --> 00:48:03,838 반면 softmax는 더더더더더좋게 성능을 높이려 할 것입니다. 537 00:48:03,838 --> 00:48:07,378 두 손실 함수 간의 흥미로운 차이점인 것입니다. 538 00:48:07,378 --> 00:48:15,966 실제 딥러닝 애플리케이션에서 두 손실 함수 간의 성능 차이는 엄청나게 크진 않습니다만 539 00:48:15,966 --> 00:48:19,970 그렇긴 해도 차이를 알고 있는 것은 유용할 것입니다. 540 00:48:23,054 --> 00:48:26,176 자 이제 지금까지 한 것들을 정리해 보자면 541 00:48:26,176 --> 00:48:29,585 우선 우리에게 데이터 셋 x와 y가 있습니다. 542 00:48:29,585 --> 00:48:36,595 우선 입력 x로부터 스코어를 얻기 위해 Linear classifier를 사용 할 것입니다. 543 00:48:36,595 --> 00:48:48,954 softmax, svm loss와 같은 손실함수를 이용해서, 모델의 예측값이 정답 값에 비해 "얼마나 구린지"를 측정합니다. 544 00:48:48,954 --> 00:48:59,059 그리고 모델의 "복잡함" 과 "단순함" 을 통제하기 위해 손실 함수에 regularization term을 추가할 것입니다. 545 00:48:59,059 --> 00:49:03,966 지금까지 우리가 Supervised leraning이라 부르는 것에 관한 전반적인 개요를 배워 보았습니다. 546 00:49:03,966 --> 00:49:12,664 우리가 딥러닝에서 배울 내용은, 어떤 엄청 복잡한 함수 f를 정의하고 547 00:49:12,664 --> 00:49:19,645 그리고는 파라미터 값이 주어졌을때 알고리즘이 얼마나 "구리게" 동작하고 있는지 측정할 손실 함수를 작성하고 548 00:49:19,645 --> 00:49:24,260 그리고 모델이 복잡해 지는 것을 어떻게 막을지에 대한 Regularization term을 추가합니다. 549 00:49:24,260 --> 00:49:30,866 그리고 그걸 모두 합쳐서, 최종 손실 함수가 최소가 되게 하는 가중치 행렬이자 파라미터인 행렬W를 구하게 되는 것입니다. 550 00:49:30,866 --> 00:49:37,132 자 이제 다음 질문은, 실제로 어떻게 해야 하는 것일까요? 어떻게 실제 Loss를 줄이는 W를 찾을 수 있는 걸까요? 551 00:49:37,132 --> 00:49:40,461 이 질문은 우리를 "최적화" 라는 주제로 이끌어 줍니다. 552 00:49:40,461 --> 00:49:47,482 최적화를 하고 있다는걸 상상해보면, 우리가 엄청 큰 계곡을 걷고 있는 것 같습니다. 553 00:49:47,482 --> 00:49:54,183 여러분은 다양한 산과 계곡과 시내가 있는 엄청 큰 골짜기를 거닐고 있는 것입니다. 554 00:49:54,183 --> 00:50:00,729 그리고 "산"과 "계곡" 과 같은 풍경들이 바로 파라미터 W입니다. 555 00:50:00,729 --> 00:50:04,517 그리고 여러분이 이 골짜기를 돌아다니는 한 사람인 것이고, 556 00:50:04,517 --> 00:50:10,728 내가 있는 곳의 "높이" 가 바로 Loss 인 것입니다. Loss는 W에 따라 변하게 되고, 우리는 W를 찾아야 합니다. 557 00:50:10,728 --> 00:50:14,181 여러분의 임무는 이곳을 돌아다니는 한 사람이 되어 558 00:50:14,181 --> 00:50:18,000 어떻게든 이 골짜기의 밑바닥을 찾아내는 것입니다. 559 00:50:18,000 --> 00:50:20,517 하지만 그런 문제들은 일반적으로 엄청 어렵습니다. 560 00:50:20,517 --> 00:50:27,379 만약 여러분이 엄청 똑똑해서 손실함수와 regularization 등 모든 것들의 속성 하나 하나를 다 분석해 냈다면 561 00:50:27,379 --> 00:50:35,509 어쩌면 제가 골짜기의 밑바닥으로 마법같이 순간이동할 수 있는 minimizer를 만들어낼 수도 있겠 습니다만 562 00:50:35,509 --> 00:50:44,609 하지만 실제로 NN을 사용하면 "예측 함수", "손실함수", "Regularizer" 같은 것들이 엄청 크고 복잡해 져서 563 00:50:46,190 --> 00:50:52,017 어떤 명시적인 솔루션을 만들어내서 최적의 솔루션(minima)를 직접 얻어내는 것은 불가능 할 것입니다. 564 00:50:52,017 --> 00:50:55,485 그래서 실제로 우리는 다양한 "iterative한 방법"들을 씁니다. 565 00:50:55,485 --> 00:51:00,524 이 방법들은 임의의 지점에서 시작해서 점차적으로 성능을 향상시키는 방법입니다. 566 00:51:00,524 --> 00:51:06,985 우선, 가장 먼저 생각해 볼 수 있는 단순한 방법은 임의 탐색(random search) 입니다. 567 00:51:06,985 --> 00:51:14,963 임의로 샘플링한 W들을 엄청 많이 모아놓고 Loss를 계산해서 어떤 W가 좋은지를 살펴보는 것입니다. 568 00:51:14,963 --> 00:51:18,828 미리 말씀드리자면 정말 구린 알고리즘이고 여러분들은 절대로 이 방법은 쓰지 마셔야 합니다. 569 00:51:18,828 --> 00:51:23,323 하지만 한번쯤 "상상"해 볼 법한 방법이긴 합니다. 570 00:51:23,323 --> 00:51:30,813 실제로 해 볼수도 있긴 합니다. 임의 탐색으로 Linear Classfier을 학습시킬 수 있습니다. 571 00:51:30,813 --> 00:51:39,768 CIFAR-10에서 클래스는 10개이니까 임의 확률은 10%가 되고, 무작위 시행을 거치게 되면, 572 00:51:39,768 --> 00:51:45,645 소가 뒷걸음질 치는 격으로 어떤 W를 구해 볼 수 있는데 이 예시에서는 15%의 정확도를 보이는군요 573 00:51:45,645 --> 00:51:53,831 10개중 하나 찍는것 보단 좋지만, 최신 알고리즘의 성능 (SOTA)이 95%라는 점을 생각하면, 격차가 좀 많이 나죠 574 00:51:53,831 --> 00:52:00,677 실제로는 이렇게 하지 마시고 이런 방법도 "가능은 하다" 정도로만 알고 넘어가시면 되겠습니다. 575 00:52:00,677 --> 00:52:06,168 실제로 더 나은 전략은 지역적인 기하학적 특성을 이용하는 것입니다. (local geometry) 576 00:52:06,168 --> 00:52:09,910 만일 여러분이 이 계곡을 걷고있는 사람이라면 577 00:52:09,910 --> 00:52:13,802 여러분이 계곡의 밑바닥이 어디인지 두 눈으로 확인할 수는 없을 것입니다. 578 00:52:13,802 --> 00:52:19,531 하지만 두 발로 느끼고 그곳의 지형을 파악할 수 있을 것입니다. 579 00:52:20,697 --> 00:52:24,145 제가 여기에 이렇게 서있다면 어떤 방향으로 가야 내려갈 수 있을까요? 580 00:52:24,145 --> 00:52:30,861 여러분은 두 발로 땅의 경사를 느끼고, 어느 방향으로 가야 내려갈 수 있을지를 알 수 있을 것입니다. 581 00:52:30,861 --> 00:52:36,260 이제 그 방향으로 한발자국 내딛고는 조금 걸어내려 가다가는, 다시 두 발로 느끼고 방향을 다시 찾아봅니다. 582 00:52:36,260 --> 00:52:41,526 이렇게 반복하다 보면 결국 여러분은 골짜기를 다 내려갈 수 있을 것입니다. 583 00:52:41,526 --> 00:52:50,195 이 알고리즘이 엄청 쉬워보이지만, 실제로 정말 잘 동작합니다. 만약 여러분이 세부 사항을 잘 파악한다면 말이죠 584 00:52:50,195 --> 00:52:57,028 이 방법은 우리가 NN이나 Linear classifer 같은 것들을 훈련시킬 때 일반적으로 사용하는 방법입니다. 585 00:52:57,028 --> 00:52:58,769 지금까지는 대략적인 감만 설명해 드린 것입니다. 586 00:52:58,769 --> 00:52:59,952 그렇다면 경사(slope)는 무엇일까요? 587 00:52:59,952 --> 00:53:07,673 미분 수업이 기억나시나요? 1차원 공간에서 경사(slope)는 어떤 함수에 대한 미분값입니다. 588 00:53:07,673 --> 00:53:12,969 1차원 함수 f가 있다고 해봅시다. f(x) = y x를 입력으로 받으면, 출력은 어떤 커브의 높이겠죠 589 00:53:12,969 --> 00:53:16,460 곡선의 일부를 구하면 기울기를 계산할 수 있습니다. 590 00:53:16,460 --> 00:53:19,717 이제 어떤 점(x)에서의 경사, 즉 도함수(derivative)를 계산해보면 591 00:53:19,717 --> 00:53:29,798 작은 스텝 , h가 있고 이 스텝 간의 함수 값의 차이를 비교해 본다면 f(x+h) - f(x) 592 00:53:29,798 --> 00:53:34,895 그리고 그 스텝사이즈를 0으로 만들면 (h->0) 그것이 바로 어떤 점에서의 이 함수의 경사가 됩니다. 593 00:53:34,895 --> 00:53:38,333 그리고 이 수식은 다변수함수(multi-variable functions) 에서로 확장시킬 수 있습니다. 594 00:53:38,333 --> 00:53:42,612 실제로 x는 스칼라(값이 하나) 가 아니라 벡터 입니다. 595 00:53:42,612 --> 00:53:51,941 x가 벡터이기 때문에 위의 개념을 다변수로 확장시켜야 합니다. 596 00:53:51,941 --> 00:54:01,168 다변수인 상황에서의 미분으로 일반화시켜보면 gradient이고 gradient는 벡터 x의 각 요소를 편도함수들의 집합입니다. 597 00:54:01,168 --> 00:54:04,409 gradient의 모양은 x와 같습니다. (입력이 3개면 gradient도 3개) 598 00:54:04,409 --> 00:54:12,391 그리고 gradient 의 각 요소가 알려주는 것은 바로 "우리가 그쪽으로 갈때 함수 f의 경사가 어떤지" 라는 것입니다. 599 00:54:12,391 --> 00:54:21,036 gradient를 통해 그런 유용한 정보를 얻을 수 있는 것입니다. gradient는 편도함수들의 벡터입니다. 600 00:54:21,036 --> 00:54:25,657 gradient의 방향은 함수에서 "가장 많이 올라가는 방향" 이 됩니다. 601 00:54:25,657 --> 00:54:31,612 반대로 생각해보면, gradient의 반대 반향이라면 "가장 많이 내려갈 수 있는 방향" 이 되는 것입니다. 602 00:54:31,612 --> 00:54:37,418 그렇다면, 여러분이 만약에 특정 방향에서 얼마나 가파른지 알고싶으면 어떻게 해야 할까요? 603 00:54:37,418 --> 00:54:42,693 이는 그 방향의 유닛벡터와 gradient벡터를 내적할 것과 같습니다. 604 00:54:42,693 --> 00:54:50,198 gradient는 매우 중요합니다. 왜냐하면 gradient가 함수의 어떤 점에서의 선형 1차근사 함수를 알려주기 때문입니다. 605 00:54:50,198 --> 00:54:53,661 그래서 실제로 많은 딥러닝 알고리즘들이 gradient를 계산하고 606 00:54:53,661 --> 00:54:58,123 그 gradient를 여러분들이 파라미터 벡터를 반복적으로 업데이트할 때 사용하는 것입니다. 607 00:54:59,204 --> 00:55:04,812 컴퓨터로 이 gradient를 써먹을 수 있는 가장 단순한 방법 중 하나는 608 00:55:04,812 --> 00:55:06,955 유한 차분법(finite difference methods)를 이용하는 것입니다. 609 00:55:06,955 --> 00:55:09,488 다시 gradient의 극한 식으로 돌아가 봅시다. 610 00:55:09,488 --> 00:55:14,012 자 여기 왼쪽은 보면 파라미터 벡터 W가 있습니다. 611 00:55:14,012 --> 00:55:17,432 이 W를 사용하면 1.25정도의 Loss를 가지는군요 612 00:55:17,432 --> 00:55:23,922 우리가 할 일은 gradient "dW" 를 구하는 것입니다. W와 모양은 같습니다. 613 00:55:23,922 --> 00:55:31,734 그리고 gradient의 각 요소가 말해주는 것은 우리가 그쪽 방향으로 아주 쬐끔 이동했을 때 Loss가 어떻게 변하는지 입니다. 614 00:55:31,734 --> 00:55:35,741 이걸 간단하게 유한 차분법으로 계산해 봅시다. 615 00:55:35,741 --> 00:55:41,902 일단 W가 있고, 지금 할 일은 W의 첫번째 요소(0.34) 에 아주 작은 값 h를 더해 보는 것입니다. 616 00:55:41,902 --> 00:55:45,842 그리고 loss를 다시 계산해 봅니다. 617 00:55:45,842 --> 00:55:53,792 여기에서 알 수 있는 것은, 우리가 첫 번째 요소를 조금 움직이면 Loss가 1.2534에서 1.25322로 감소한다는 것입니다. 618 00:55:55,945 --> 00:56:04,378 이제 극한 식을 이용해서 FDM으로 근사시킨 gradient를 구합니다. 619 00:56:04,378 --> 00:56:07,795 두 번째 요소에서도 이를 반복할 수 있겠습니다. 620 00:56:07,795 --> 00:56:13,728 이제 다시 첫 번째 요소의 값은 원래대로 돌려놓고 두 번째 요소를 아주 조금 증가시킵니다. 621 00:56:13,728 --> 00:56:21,165 그리고 다시 Loss를 계산하고 FDM을 이용해서 두 번째 요소 gradient의 근사치를 계산해 볼 수 있습니다. 622 00:56:21,165 --> 00:56:25,135 이런 세번째에도 하고 계속 반복합니다. 623 00:56:25,135 --> 00:56:29,150 이건 실제로는 정말 끔질한 방법입니다. 시간이 엄청 오래걸리거든요 624 00:56:29,150 --> 00:56:35,920 이 함수 f가 CNN같이 엄청 큰 함수였다면. 엄청 오래 걸렸을 것입니다. 625 00:56:35,920 --> 00:56:40,693 그리고 파라미터 W가 여기서는 10개뿐이 없지만 626 00:56:40,693 --> 00:56:46,446 엄청 크고 깊은 신경망이라면 파라미터가 수천 수억개 일 수도 있습니다. 627 00:56:46,446 --> 00:56:50,381 따라서 실제로는 이런식으로 gradient를 계산하지 않습니다. 628 00:56:50,381 --> 00:56:56,908 왜냐면 gradient 하나를 구하려고 수천개의 함수값을 일일이 다 계산해야 하기 떄문입니다. 629 00:56:56,908 --> 00:56:58,075 이건 엄청 느리고 안좋습니다. 630 00:56:59,351 --> 00:57:05,315 아마도 여러분들이 살면서 한번쯤은 미적수업을 들은적이 있을 것입니다. 631 00:57:05,315 --> 00:57:11,206 여기 이 두분들 덕분에, 우리는 단지 손실함수를 적어놓기만 하고 632 00:57:11,206 --> 00:57:17,372 미분이라는 마법의 헤머를 두드리기만 하면 gradient가 계산되어 나옵니다. 633 00:57:17,372 --> 00:57:21,658 해적적으로 푸는 것이 수치적으로 푸는 것 보다 더 효율적입니다. 634 00:57:21,658 --> 00:57:27,350 일단 더 정확하기도 할 뿐더러, 식 하나로 계산할 수 있기 때문에 계산 도 훨씬 더 빠릅니다. 635 00:57:28,945 --> 00:57:33,513 다시 W 그림으로 돌아가 봅시다. 636 00:57:33,513 --> 00:57:36,848 W 의 모든 원소를 순회하는 것이 아니라 637 00:57:36,848 --> 00:57:40,653 gradient를 나타내는 식이 뭔지만 먼저 찾아내고 638 00:57:40,653 --> 00:57:47,337 그걸 수식으로 내타내서 한번에 gradient dW를 계산해 버리는 것입니다. 639 00:57:47,337 --> 00:57:50,875 실제로 이 방법이 훨씬 더 좋습니다. 640 00:57:50,875 --> 00:57:56,738 요약하자면, 앞서 말한 수치적인 gradient는 간단하고 그럴듯 하긴 하지만 641 00:57:56,738 --> 00:57:58,745 실제로는 사용하지 않는다는 것입니다. 642 00:57:58,745 --> 00:58:05,301 실제 gradient 계산을 구현할때는 분석적인 방법을 이용합니다. 643 00:58:05,301 --> 00:58:10,610 하지만 흥미로운 점은 이런 수치적 gradient도 디버깅 툴로는 유용할 수 있다는 것입니다. 644 00:58:12,572 --> 00:58:17,770 우리가 Loss의 gradient를 계산하는 코드를 짜고 있다고 해봅시다. 645 00:58:17,770 --> 00:58:19,562 그것을 어떻게 디버깅하시겠습니까? 646 00:58:19,562 --> 00:58:25,684 여러분이 작성한 미분 코드가 잘 작동하는지를 어떻게 확인하실 것입니까? 647 00:58:25,684 --> 00:58:31,159 그런 상황에 흔히들 쓰는 방법은 바로 이 수치적 gradient를 사용하는 것입니다. 648 00:58:31,159 --> 00:58:35,141 유닛 테스트의 일종으로 여러분들의 코드를 확인할 수 있습니다. 649 00:58:35,141 --> 00:58:41,435 하지만 수치적인 방법은 엄청 느리고 부정확 하므로 이를 디버깅에 이용하고자 한다면 650 00:58:41,435 --> 00:58:46,755 파라미터의 스케일을 줄이는 편이 좋습니다. 그래야 디버깅이 오래 걸리지 않을 것입니다. 651 00:58:46,755 --> 00:58:51,721 여러분만의 gradient 계산 코드를 짤때 쓸만한 유용한 디버깅 전략 하나는 소개시켜 드렸습니다. 652 00:58:51,721 --> 00:58:58,610 실제로도 정말 많이 사용하고, 여러분들도 과제에서 사용하게 될 것입니다. 653 00:58:58,610 --> 00:59:01,834 일단 우리가 gradient를 계산하는 방법을 알고 나면 654 00:59:01,834 --> 00:59:13,152 이 세 줄짜리 간단한 알고리즘은 엄청 크고 복잡하고 싶은 신경망 알고리즘을 어떻게 학습시킬지에 대한 핵심 아이디어를 담 고 있습니다. 655 00:59:13,152 --> 00:59:19,544 Gradient Descent에서는 우선 W를 임의의 값으로 초기화합니다. 656 00:59:19,544 --> 00:59:27,547 그리고 Loss와 gradient를 계산한 뒤에 가중치를 gradient의 반대 방향으로 업데이트합니다. 657 00:59:27,547 --> 00:59:34,047 gradient가 함수에서 증가하는 방향이기 때문에 -gradient를 해야 내려가는 방향이 되는 것입니다. 658 00:59:34,047 --> 00:59:40,774 그러니 -gradient 방향으로 아주 조금씩 이동할 것이고 이걸 영원히 반복하다 보면 결국에는 수렴할 것입니다. 659 00:59:40,774 --> 00:59:43,255 그렇게 되면 엄청 행복하겠지요... 660 00:59:43,255 --> 00:59:50,842 하지만 스텝 사이즈는 하이퍼 파라미터 입니다. 스텝 사이즈는 그 -gradient 방향으로 얼마나 나아가야 하는지를 알려줍니다. 661 00:59:50,842 --> 01:00:00,033 스텝사이즈는 Learning rate라고도 하며, 실제 학습을 할때 여러분이 정해줘 야 하는 가장 중요한 하이퍼파라미터 중 하나입니다. 662 01:00:00,033 --> 01:00:07,502 저의 경우에는 트레이닝을 시작할때 Leraning Rate는 제가 가장 먼저 체크하는 하이퍼파라미터입니다. 663 01:00:07,502 --> 01:00:12,434 모델 사이즈라던지 Regularization 의 강도라던지 하는 것들은 우선 나중으로 미뤄두고 664 01:00:12,434 --> 01:00:19,361 Learning rate를 올바르게 정해주는 것을 가장 먼저 합니다. 665 01:00:19,361 --> 01:00:25,212 여기 그림을 보면 2차원 공간의 아주 간단한 예시가 있습니다. 666 01:00:25,212 --> 01:00:30,051 여기 그릇처럼 보이는 것이 손실합수 입니다. 667 01:00:30,051 --> 01:00:36,598 가운데 빨간 부분이 낮은 Loss인 것이고 668 01:00:36,598 --> 01:00:41,187 테두리의 파란영역과 초록 영역은 Loss가 더 높은 곳입니다. 피해가야 겠죠 669 01:00:41,187 --> 01:00:44,750 자 이제 임의의 점에 W를 설정해 두겠습니다. 670 01:00:44,750 --> 01:00:51,387 이제 우리는 -gradient를 계산할 것이고 이를 통해 우리는 결국 가장 낮은 지점에 도달할 것입니다. 671 01:00:51,387 --> 01:00:56,407 그리고 이걸 계속 반복하게 되면 아마도 결국은 정확한 최저점에 도달하게 될 것입니다. 672 01:00:56,407 --> 01:01:04,358 실제로 한번 봅시다. 673 01:01:04,358 --> 01:01:15,266 우선 임의의 점에서 시작해서 매번 조금씩 계속 이동하는 것입니다. 674 01:01:15,266 --> 01:01:20,626 그리고 파라미터가 최저점으로 휘어져 들어가는 것을 볼 수 있습니다. 675 01:01:20,626 --> 01:01:24,241 우리가 낮은 loss를 원했기 때문에 이것은 정확히 우리가 바라던 것입니다. 676 01:01:24,241 --> 01:01:33,998 하지만 지금까지 본 예제는 아주 단순한 방법입니다. 매 스텝마다 -gradient의 방향으로만 이동한 뿐이죠 677 01:01:33,998 --> 01:01:40,885 하지만 다음 몇 강의동안 여러분은 더 쩌는 스텝을 볼 수 있을 것입니다. Update Rule 이라고도 하는 방법이죠 678 01:01:40,885 --> 01:01:46,037 여러 스텝을 한번에 고려하는 더 쩌는 방법들이 존재합니다. 679 01:01:46,037 --> 01:01:54,610 기본적인 Gradient descent보다 실제 학습시에 더 좋은 성능을 보이는 것들입니다. 680 01:01:54,610 --> 01:02:01,054 맛보기로, 같은 문제를 푸는 다른 개쩌는 방법들을 몇가지 보여드리겠습니다. 681 01:02:01,054 --> 01:02:07,530 검정색은 이전에 본 것과 같은 스텝인 것이고 나머지 둘중 뭐가 뭔지 기억이 잘 안나지만 682 01:02:07,530 --> 01:02:11,580 어쨋든 나머지 두개는 좀 더 쩌는 Update rules입니다. 683 01:02:11,580 --> 01:02:15,929 이 방법들은 다음 스텝에 현재의 gradient 정보를 이용합니다. 684 01:02:15,929 --> 01:02:22,835 하나는 momentum을 이용한 것이고 다른 하나는 Adam optimizer를 이용한 방법입니다. 685 01:02:22,835 --> 01:02:25,389 저 자세한 사항은 다음 수업에서 다루도록 하겠습니다. 686 01:02:25,389 --> 01:02:29,795 그 방법들의 핵심은, Gradient Descent라는 기본적인 알고리즘을 사용하고 있고 687 01:02:29,795 --> 01:02:33,424 다음 스텝을 결정하기 위해서 이전의 모든 스텝의 gradient정보를 이용하는 것입니다. 688 01:02:33,424 --> 01:02:38,559 그래서 gradient 정보를 정확히 어떻게 이용할 것이냐 에 따라서 여러 Update rule이 존재하긴 하지만 689 01:02:38,559 --> 01:02:44,058 결국 기본적인 알고리즘은 바로 매 스텝 아래로 내려가는 것입니다. 690 01:02:50,022 --> 01:02:53,212 우리가 배워야 할 또 한가지가 있습니다. 691 01:02:53,212 --> 01:03:02,237 손실 함수를 정의했던 것을 생각해보면, Loss는 각 트레이닝 샘플을 분류기가 얼마나 "구리게" 분류하는지를 계산하는 것이였고 692 01:03:02,237 --> 01:03:08,314 그리고 전체 Loss는 전체 트레이닝 셋 Loss의 평균으로 사용했습니다. 693 01:03:08,314 --> 01:03:12,572 하지만 실제로는 N이 엄청 커 질수도 있습니다. 694 01:03:12,572 --> 01:03:19,199 첫 강의에서 말했던 ImageNet 데이터셋을 생각해보면 N은 130만개 입니다. 695 01:03:19,199 --> 01:03:23,208 따라서 Loss를 계산하는건 정말 오래 걸리는 작업이 됩니다. 696 01:03:23,208 --> 01:03:29,821 아마 수백만번의 계산이 필요한 것입니다. 그래서 그것은 정말로 느릴 수 있습니다. 697 01:03:29,821 --> 01:03:32,094 사실 gradient 는 선형 연산자 이기 때문에 698 01:03:32,094 --> 01:03:41,461 실제 gradient를 계산하는 과정을 살펴보면, Loss는 그저 각 데이터 Loss의 Gradient의 합이라는 것을 알 수 있습니다. 699 01:03:41,461 --> 01:03:48,469 그러니 gradient를 한번 더 계산하려면 , N개의 전체 트레이닝 셋 을 한번 더 돌면서 계산해야 하는 것입니다. 700 01:03:48,469 --> 01:03:56,978 N이 100만 이라면 엄청 느리게 되겠죠. W가 일일이 업데이트 되려면 엄청나게 많은 시간을 기다려야 할 것입니다. 701 01:03:56,978 --> 01:04:00,728 그래서 실제로는 stochastic gradient descent 라는 방법을 씁니다. 702 01:04:00,728 --> 01:04:05,697 전체 데이터 셋의 gradient과 loss를 계산하기 보다는 703 01:04:05,697 --> 01:04:12,540 Minibatch라는 작은 트레이닝 샘플 집합으로 나눠서 학습하는 것입니다. 704 01:04:12,540 --> 01:04:17,705 Minibatch는 보통 2의 승수로 정하며 32, 64, 128 을 보통 씁니다. 705 01:04:17,705 --> 01:04:25,047 따라서 이 작은 minibatch를 이용해서 Loss의 전체 합의 "추정치"와 실제 gradient의 "추정치"를 계산하는 것입니다. 706 01:04:25,047 --> 01:04:33,345 그래서 stochastic 하다는 것은 Monte Carlo Method의 실제 값 추정 방법과 유사하다고 볼 수 있습니다. 707 01:04:34,716 --> 01:04:38,945 알고리즘이 더 쩔어 졌지만 코드는 여전히 4줄이면 충분합니다. 708 01:04:38,945 --> 01:04:48,690 이제는 임의의 minibatch를 만들어내고, minibatch에서 Loss와 Gradient를 계산합니다. 그리고 W를 업데이트합니다. 709 01:04:48,690 --> 01:04:53,661 Loss의 "추정치" 와 Gradient의 "추정치" 를 사용하는 것입니다. 710 01:04:53,661 --> 01:04:59,811 그리고 앞으로, 이 좀 더 간지나는 Update Rules이 정확히 어떻게 여러 gradients들을 통합시키는지 알아 볼 것입니다. 711 01:04:59,811 --> 01:05:05,948 그리고 SGD는 거의 모든 DNN알고리즘에 사용되는 기본적인 학습 알고리즘입니다. 712 01:05:06,875 --> 01:05:14,970 Linear classifier를 이용해서 SGD로 어떻게 이것을 학습 시키는 지에 대한 웹 데모를 준비했습니다만 713 01:05:14,970 --> 01:05:23,269 지난 시간에 웹데모를 실패했기 때문에 실제 링크를 열지 않고 비디오로 보여드리겠습니다. 714 01:05:23,269 --> 01:05:25,339 [웃음] 715 01:05:25,339 --> 01:05:27,749 온라인에서 한번 접속해 보세요 716 01:05:27,749 --> 01:05:32,735 Linear classifier와 이를 Gradient descent로 학습 시키는 것에 대한 직관을 얻을 수 있습니다. 717 01:05:32,735 --> 01:05:40,146 여기 왼쪽에는 세개의 카테고리 클래스를 볼 수 있습니다. 718 01:05:40,146 --> 01:05:45,753 여기 초록, 파랑, 빨간 점들이 있고 이 점들이 트레이닝 샘플입니다. 719 01:05:45,753 --> 01:05:52,068 그리고 각 클래스에 해당하는 결정 경계를 그려 놨습니다. 배경 색은 해당하는 지역입니다. 720 01:05:52,068 --> 01:05:59,007 뿐만 아니라 방향도 있는데, 이 방향은 갹 세개의 클래스 스코어가 증가하는 방향입니다. 721 01:05:59,007 --> 01:06:12,176 그리고 접속해서 실제로 해보면 실제 W를 조정할 수가 있습니다. W를 조절하면 결정 경계가 회전하는 것을 볼 수 있습니다. 722 01:06:12,176 --> 01:06:18,662 Bias를 조정하면 결정경계가 회전하지 않고 위아래로만 움직입니다. 723 01:06:18,662 --> 01:06:21,855 스텝도 만들어 놨습니다. W를 업데이트도 할 수 있죠 724 01:06:21,855 --> 01:06:26,009 슬라이드바를 사용해서 스텝사이즈를 변경할 수 있습니다. 725 01:06:26,009 --> 01:06:32,874 스텝 사이즈를 크게 잡으니 , 지금 GD를 돌리고 있는데 결정 경계가 데이터에 핏하려고 날뛰고 있군요 726 01:06:34,553 --> 01:06:39,890 이제 날뛰지 않는군요. 그리고 손실 함수도 실시간으로 바뀔 수 있습니다. 727 01:06:39,890 --> 01:06:43,567 여러 SVM과 softmax 를 사용할 수 있습니다. 728 01:06:43,567 --> 01:06:50,219 그리고 여러분이 다양한 손실 함수를 적용해 보게 되면 손실 함수들이 일반적으로 같은 일을 하고 있다는 것을 알 수 있습니다. 729 01:06:50,219 --> 01:06:52,340 나눠진 지역들이 알고리즘 마다 비슷하긴 하지만 730 01:06:52,340 --> 01:06:54,945 결국 각각이 어떻게 학습이 종료되는지를 확인해보고 731 01:06:54,945 --> 01:07:00,743 여러 요소들의 trade-off를 따져보게 되면 조금씩 다르다는 것을 알 수 있습니다. 732 01:07:00,743 --> 01:07:09,178 그러니 GD를 통해 Linear classifier를 학습시키는게 실제로 어떻게 생겼는지를 보면서 직관을 얻으셨으면 좋겠습니다. 733 01:07:12,343 --> 01:07:16,245 이제 좀 다른 얘기를 해볼까 합니다. 734 01:07:16,245 --> 01:07:18,102 이미지의 특징에 관한 것입니다. 735 01:07:18,102 --> 01:07:27,434 지금까지 Linear classifier에 대해 이야기해 보았습니다. 실제 Raw 이미지 픽셀을 입력으로 받는 방식이었죠 736 01:07:28,464 --> 01:07:33,343 지난 강의에서 말씀 드렸듯이 이런 방법은 좋은 방법은 아닙니다. 737 01:07:33,343 --> 01:07:36,233 Multi-Modality 와 같은 것들 때문이죠 (말 머리 두개) 738 01:07:36,233 --> 01:07:42,789 실제로는 영상 자체를 입력으로 사용하는 것은 성능이 좋지 않습니다. 739 01:07:42,789 --> 01:07:49,592 그래서 DNN이 유행하기 전에 주로 쓰는 방법은 두가지 스테이지를 거치는 방법이었습니다. 740 01:07:49,592 --> 01:07:53,916 첫번 째는, 이미지가 있으면 여러가지 특징 표현을 계산하는 것입니다. 741 01:07:53,916 --> 01:08:00,179 이런 특징 표현은 이미지의 모양새와 관련된 것일 수 있습니다. 742 01:08:00,179 --> 01:08:05,137 그리고 여러 특징 표현들은 한데 연결시켜(Concat) 하나의 특징 벡터로 만듭니다. 743 01:08:05,137 --> 01:08:12,902 그러면 이 특징 벡터가 Linear classifier의 입력으로 들어가는 것입니다. 744 01:08:12,902 --> 01:08:17,700 여기에서의 모티브는 , 여기 그림과 같은 트레이닝 셋이 있다고 해 보면 745 01:08:17,701 --> 01:08:22,244 빨간 점들이 가운데 있고 그 주변에 파란 점들이 있죠 746 01:08:22,244 --> 01:08:29,157 이런 데이터 셋의 경우에는 Linear한 결정 경제를 그릴 방법이 없는 것입니다. 747 01:08:29,157 --> 01:08:32,155 이런 예시를 지난 강의에서 더 살펴 봤었습니다. 748 01:08:32,156 --> 01:08:36,660 만약 우리가 적절하게 특징 변환을 해본다면, 이경우에는 극좌표계로 바꾼 것입니다. 749 01:08:36,660 --> 01:08:43,677 그 복잡하던 데이터가, 변환 후에 선형으로 분리가 가능하게 바뀌었습니다. 750 01:08:43,677 --> 01:08:46,858 실제로도 Linear classifier로 완벽하게 분리할 수 있습니다. 751 01:08:46,858 --> 01:08:55,129 이런 기법들은 여러분의 문제를 풀 수 있도록 하려면 어떤 특징 변환이 필요한가 를 알아내는 것들입니다. 752 01:08:55,129 --> 01:08:59,751 이미지의 경우 픽셀들을 극좌표계로 바꾸는 것은 전혀 말이 안되는 일이지만 753 01:08:59,751 --> 01:09:04,749 극좌표계로 변환하는 것을 일종의 특징 변환이라 생각한다면 말이 되는 것입니다. 754 01:09:04,749 --> 01:09:10,391 그리고 이것은 실제로 분류기에 Raw 이미지를 넣는것 보다 성능이 더 좋을지도 모릅니다. 755 01:09:10,392 --> 01:09:16,343 특징 변환의 한 예를 들어보자면 컬러 히스토그램이 있습니다. 756 01:09:16,343 --> 01:09:23,985 이미지에서 Hue 값만 뽑아서 모든 픽셀을 각 양동이에 넣는 것입니다. 757 01:09:23,986 --> 01:09:31,162 한 필셀은 해당하는 색의 양동이에 넣고 각 양동이에 들어있는 픽셀의 개수를 세는 것입니다. 758 01:09:31,162 --> 01:09:34,638 이는 이미지가 적체적으로 어떤 색인지를 알려줍니다. 759 01:09:34,639 --> 01:09:40,938 이 개구리의 예를 보면 초록색이 많은걸 알 수 있습니다. 자주색이나 붉은색은 별로 없습니다. 760 01:09:40,938 --> 01:09:44,043 실제로 사용하는 간단한 특징 벡터라고 볼 수 있습니다. 761 01:09:45,108 --> 01:09:53,219 NN이 뜨기 전에 인기있었던 또 다른 특징 벡터중 하나는 바로 Histogram of oriented gradients(HOG) 입니다. 762 01:09:53,220 --> 01:10:00,046 첫 강의를 생각해보면 Hubel 과 Wiesel이 이런 Oriented edges가 인간의 시각시스템에서 정말 중요하다고 했습니다. 763 01:10:00,046 --> 01:10:09,974 HOG도 그와 같은 직관을 가지고 있으며 Local orientation edges를 측정합니다. 764 01:10:09,974 --> 01:10:16,354 실제로 하는 일을 보면 이미지가 있으면 8x8로 픽셀을 나눕니다. 765 01:10:16,354 --> 01:10:22,268 그리고 이 8x8 픽셀 지역 내에서, 가장 지배적인 edge의 방향을 계산하고 766 01:10:22,268 --> 01:10:27,776 그리고 edge directions을 양자화해서 양동이에 넣는 것입니다. 767 01:10:27,776 --> 01:10:31,857 그리고 다양한 edge oreirentations에 대한 히스토그램을 계산하는 것입니다. 768 01:10:31,857 --> 01:10:40,204 그러면 전체 특징 벡터는, 각각의 모든 8x8 지역들이 가진 "edge orientation에 대한 히스토그램" 이 되는 것입니다. 769 01:10:41,660 --> 01:10:47,029 이전에 봤던 컬러 히스토그램이랑은 좀 다르죠 770 01:10:47,029 --> 01:10:51,082 컬러 히스토그램은 이미지 전체적으로 어떤 색이 있는지를 나타냈습니다. 771 01:10:51,082 --> 01:10:55,305 반면 HOG는 이미지 내에 전반적으로 어떤 종류의 edge정보가 있는지를 나타냅니다. 772 01:10:55,305 --> 01:11:01,191 이미지를 여러 부분으로 지역화해서, 지역적으로 어떤 edge가 존재하는지도 알 수 있습니다. 773 01:11:01,191 --> 01:11:04,938 그래서 이 개구리의 경우를 보면 이파리 위에 앉아있는 것을 볼 수 있습니다. 774 01:11:04,938 --> 01:11:07,561 그리고 이파리들은 주로 대각선 edge를 가지고 있습니다. 775 01:11:07,561 --> 01:11:14,667 그리고 실제 HOG를 시각화해 보면 이파리 부분에 많은 대각 edge가 있다는 것을 알 수 있습니다. 776 01:11:14,667 --> 01:11:19,340 이것이 바로 HOG의 특징표현이 가지고 있는 것입니다. 777 01:11:19,340 --> 01:11:25,702 HOG는 영상 인식에서 정말 많이 활용한 특징벡터입니다. 엄청 오래전에 사용했던 것이 아닙니다. 778 01:11:26,573 --> 01:11:32,810 또 하나의 특징 표현이 있는데 바로 bag of words입니다. 779 01:11:32,810 --> 01:11:36,355 이 아이디어는 자연어처리(NLP)에서 영감을 받은 것인데요 780 01:11:36,355 --> 01:11:40,799 어떤 문장이 있고, BOW에서 이 문장을 표현하는 방법은 781 01:11:40,799 --> 01:11:45,732 바로 문장의 여러 단어의 발생 빈도를 세서 특징 벡터로 사용하는 것입니다. 782 01:11:45,732 --> 01:11:49,664 이 직관을 그대로 이미지에 적용한 것입니다. 783 01:11:49,664 --> 01:11:54,288 하지만 BOW를 적용하려고 하는데 이미지에 적용하려니 쉬운 문제가 아니였습니다. 784 01:11:54,288 --> 01:11:57,965 그래서 "시각 단어(visual words)"라고 하는 우리만의 용어를 정의해야 했습니다. 785 01:11:58,880 --> 01:12:01,106 여기에서는 2단계의 과정이 있습니다. 786 01:12:01,106 --> 01:12:09,723 엄청 많은 이미지를 가지고, 그 이미지들은 임의대로 조각냅니다. 그리고 그 조각들을 K-means와 같은 알고리즘으로 군집화합니다. 787 01:12:09,723 --> 01:12:17,139 이미지내의 다양한 것들을 표현할 수 있는 다양한 군집들을 만들어 내는 것입니다. 788 01:12:17,139 --> 01:12:23,335 오른쪽 예를 보면, 이것은 이미지들에서 다양한 이미지 패치를 뽑아내서 군집화 시켜 놓은 실제 예시입니다. 789 01:12:23,335 --> 01:12:30,552 군집화 단계를 거치고나면, 시각 단어(visual words)는 빨간색, 파랑색, 노랑색과 같은 다양한 색을 포착해냅니다. 790 01:12:30,552 --> 01:12:34,556 분만 아니라 다양한 종류의 다양한 방향의 oriented edges또한 포착할 수 있습니다. 791 01:12:34,556 --> 01:12:40,480 그리고 이건은 매우 흥미롭습니다. 왜냐하면 이런 edges들을 데이터 중심적인 방법을 통해 얻어낸 것이기 때문입니다. 792 01:12:40,480 --> 01:12:44,291 이런 시각 단어(visual words) 집합인 Codebook을 만들고 나면 793 01:12:44,291 --> 01:12:52,468 그러면 어떤 이미지가 있으면, 이 이미지에서의 시각 단어들의 발생 빈도를 통해서 이미지를 인코딩 할 수 있는 것입니다. 794 01:12:52,468 --> 01:12:59,427 그리고 이는 이 이미지가 어떻게 생겼는지에 대한 다양한 정보를 제공하는 것입니다. 795 01:12:59,427 --> 01:13:04,638 그리고 BOW는 Fei-Fei 교수님께서 대학원시절에 만든 것입니다. 796 01:13:04,638 --> 01:13:08,972 여러분이 지금까지 봤던 것들이 실제로 엄청 오래전에 쓰인 것이 아닙니다. 797 01:13:10,783 --> 01:13:20,886 나중에 설명한 내용이긴 하지만 Image classification의 pipleline은 이렇게 생겼습니다. 798 01:13:20,886 --> 01:13:31,173 5~10년 전까지만 해도 이미지를 입력받으면 BOW나 HOG와 같은 다양한 특징 표현을 계산하고, 799 01:13:31,173 --> 01:13:38,590 계산한 특징들을 한데 모아 연결해서, 추출된 그 특징들을 Linear classifier의 입력으로 사용했습니다. 800 01:13:38,590 --> 01:13:44,576 제가 어느정도 단순화시키긴 했지만, 대부분은 일반적으로 이런 직관이라고 보시면 되겠습니다. 801 01:13:44,576 --> 01:13:53,563 특징이 한번 추출되면 feature extractor는 classier를 트레이닝하는 동안 변하지 않습니다. 802 01:13:53,563 --> 01:13:57,907 트레이닝 중에는 오직 Linear classifier만 훈련이 됩니다. 803 01:13:57,907 --> 01:14:06,486 그리고 CNN이나 DNN으로 넘어가 보자면 실제로 크게 다르지 않습니다. 804 01:14:06,486 --> 01:14:12,687 유일하게 다른점이 있다면 이미 만들어 놓은 특징들을 쓰기 보다는 데이터로부터 특징들을 직접 학습하려 한다는 것입니다. 805 01:14:12,687 --> 01:14:21,488 터그렇기 때문에 raw 픽셀이 CNN에 그대로 들어가고 여러 레이어를 거쳐서 데이터를 통한 특징 표현을 직접 만들어냅니다. 806 01:14:21,488 --> 01:14:28,787 따라서 Linear classifier만 훈련하는게 아니라 가중치 전체를 한꺼번에 학습하는 것입니다. 807 01:14:30,329 --> 01:14:39,329 그럼 다음시간에는 CNN에 대해 더 심도깊에 살펴볼 것이고 역전파(backpropagarion) 또한 알아볼 것입니다.